feat: instances list actions
This commit is contained in:
parent
7536cdfc85
commit
6f10428b0f
@ -23,8 +23,8 @@
|
|||||||
"bootstrap": "lerna bootstrap",
|
"bootstrap": "lerna bootstrap",
|
||||||
"dev": "redrun -p dev:*",
|
"dev": "redrun -p dev:*",
|
||||||
"dev:ui-toolkit": "lerna run watch --scope joyent-ui-toolkit",
|
"dev:ui-toolkit": "lerna run watch --scope joyent-ui-toolkit",
|
||||||
"dev:cp-frontend": "lerna run start --scope joyent-cp-frontend",
|
"dev:my-joy-beta": "lerna run dev --scope my-joy-beta",
|
||||||
"dev:gql-mock-server": "lerna run dev --scope joyent-cp-gql-mock-server",
|
"dev:cloudapi-gql": "lerna run dev --scope cloudapi-gql",
|
||||||
"commitmsg": "commitlint -e",
|
"commitmsg": "commitlint -e",
|
||||||
"precommit": "cross-env CI=1 redrun -s lint-staged format-staged",
|
"precommit": "cross-env CI=1 redrun -s lint-staged format-staged",
|
||||||
"postinstall": "lerna run prepublish",
|
"postinstall": "lerna run prepublish",
|
||||||
|
@ -35,8 +35,9 @@ module.exports.start = uuid => request('startMachine', uuid);
|
|||||||
module.exports.startFromSnapshot = ctx =>
|
module.exports.startFromSnapshot = ctx =>
|
||||||
request('startMachineFromSnapshot', ctx);
|
request('startMachineFromSnapshot', ctx);
|
||||||
module.exports.reboot = ctx => request('rebootMachine', ctx);
|
module.exports.reboot = ctx => request('rebootMachine', ctx);
|
||||||
module.exports.resize = ctx => request('', ctx);
|
(module.exports.resize = ({ id, package }) =>
|
||||||
module.exports.rename = ctx => request('', ctx);
|
request.fetch(`/:login/machines/${id}?action=resize?package=${package}`)),
|
||||||
|
(module.exports.rename = ctx => request('', ctx));
|
||||||
module.exports.destroy = ctx => request('deleteMachine', ctx);
|
module.exports.destroy = ctx => request('deleteMachine', ctx);
|
||||||
module.exports.audit = ({ id }) => request('machineAudit', id);
|
module.exports.audit = ({ id }) => request('machineAudit', id);
|
||||||
|
|
||||||
|
@ -4,25 +4,35 @@ const api = require('../api');
|
|||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
account: () => api.account.get(),
|
account: () => api.account.get(),
|
||||||
|
|
||||||
keys: (root, { login, name }) =>
|
keys: (root, { login, name }) =>
|
||||||
name
|
name
|
||||||
? api.keys.get({ login, name }).then(key => [key])
|
? api.keys.get({ login, name }).then(key => [key])
|
||||||
: api.keys.list({ login, name }),
|
: api.keys.list({ login, name }),
|
||||||
|
|
||||||
key: (root, { login, name }) => api.keys.get({ login, name }),
|
key: (root, { login, name }) => api.keys.get({ login, name }),
|
||||||
|
|
||||||
users: (root, { id }) =>
|
users: (root, { id }) =>
|
||||||
id ? api.users.get({ id }).then(user => [user]) : api.users.list(),
|
id ? api.users.get({ id }).then(user => [user]) : api.users.list(),
|
||||||
|
|
||||||
user: (root, { id }) => api.users.get({ id }),
|
user: (root, { id }) => api.users.get({ id }),
|
||||||
|
|
||||||
roles: (root, { id, name }) =>
|
roles: (root, { id, name }) =>
|
||||||
id || name
|
id || name
|
||||||
? api.roles.get({ id, name }).then(role => [role])
|
? api.roles.get({ id, name }).then(role => [role])
|
||||||
: api.roles.list(),
|
: api.roles.list(),
|
||||||
|
|
||||||
role: (root, { id, name }) => api.roles.get({ id, name }),
|
role: (root, { id, name }) => api.roles.get({ id, name }),
|
||||||
|
|
||||||
policies: (root, { id }) =>
|
policies: (root, { id }) =>
|
||||||
id
|
id
|
||||||
? api.policies.get({ id }).then(policy => [policy])
|
? api.policies.get({ id }).then(policy => [policy])
|
||||||
: api.policies.list(),
|
: api.policies.list(),
|
||||||
|
|
||||||
policy: (root, { id }) => api.policies.get({ id }),
|
policy: (root, { id }) => api.policies.get({ id }),
|
||||||
|
|
||||||
config: () => api.config().then(toKeyValue),
|
config: () => api.config().then(toKeyValue),
|
||||||
|
|
||||||
datacenters: () =>
|
datacenters: () =>
|
||||||
api.datacenters().then(dcs =>
|
api.datacenters().then(dcs =>
|
||||||
Object.keys(dcs).map(name => ({
|
Object.keys(dcs).map(name => ({
|
||||||
@ -30,17 +40,23 @@ const resolvers = {
|
|||||||
url: dcs[name]
|
url: dcs[name]
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
|
|
||||||
services: () => api.services().then(toKeyValue),
|
services: () => api.services().then(toKeyValue),
|
||||||
|
|
||||||
images: (root, { id, ...rest }) =>
|
images: (root, { id, ...rest }) =>
|
||||||
id
|
id
|
||||||
? api.images.get({ id }).then(image => [image])
|
? api.images.get({ id }).then(image => [image])
|
||||||
: api.images.list(rest),
|
: api.images.list(rest),
|
||||||
|
|
||||||
image: (root, { id }) => api.images.get({ id }),
|
image: (root, { id }) => api.images.get({ id }),
|
||||||
|
|
||||||
packages: (root, { id, ...rest }) =>
|
packages: (root, { id, ...rest }) =>
|
||||||
id
|
id
|
||||||
? api.packages.get({ id }).then(pkg => [pkg])
|
? api.packages.get({ id }).then(pkg => [pkg])
|
||||||
: api.packages.list(rest),
|
: api.packages.list(rest),
|
||||||
|
|
||||||
package: (root, { id, name }) => api.packages.get({ id, name }),
|
package: (root, { id, name }) => api.packages.get({ id, name }),
|
||||||
|
|
||||||
machines: (root, { id, brand, state, tags, ...rest }) =>
|
machines: (root, { id, brand, state, tags, ...rest }) =>
|
||||||
id
|
id
|
||||||
? api.machines.get({ id }).then(machine => [machine])
|
? api.machines.get({ id }).then(machine => [machine])
|
||||||
@ -51,36 +67,45 @@ const resolvers = {
|
|||||||
tags: fromKeyValue(tags)
|
tags: fromKeyValue(tags)
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
|
|
||||||
machine: (root, { id }) => api.machines.get({ id }),
|
machine: (root, { id }) => api.machines.get({ id }),
|
||||||
|
|
||||||
snapshots: (root, { name, machine }) =>
|
snapshots: (root, { name, machine }) =>
|
||||||
name
|
name
|
||||||
? api.machines.snapshots
|
? api.machines.snapshots
|
||||||
.get({ id: machine, name })
|
.get({ id: machine, name })
|
||||||
.then(snapshot => [snapshot])
|
.then(snapshot => [snapshot])
|
||||||
: api.machines.snapshots.list({ id: machine }),
|
: api.machines.snapshots.list({ id: machine }),
|
||||||
|
|
||||||
snapshot: (root, { name, machine }) =>
|
snapshot: (root, { name, machine }) =>
|
||||||
api.machines.snapshots.get({ name, id: machine }),
|
api.machines.snapshots.get({ name, id: machine }),
|
||||||
|
|
||||||
metadata: (root, { machine, name, ...rest }) =>
|
metadata: (root, { machine, name, ...rest }) =>
|
||||||
name
|
name
|
||||||
? api.machines.metadata
|
? api.machines.metadata
|
||||||
.get(Object.assign(rest, { id: machine, key: name }))
|
.get(Object.assign(rest, { id: machine, key: name }))
|
||||||
.then(value => toKeyValue({ [name]: value }))
|
.then(value => toKeyValue({ [name]: value }))
|
||||||
: api.machines.metadata.list({ id: machine }).then(toKeyValue),
|
: api.machines.metadata.list({ id: machine }).then(toKeyValue),
|
||||||
|
|
||||||
metadataValue: (root, { name, machine }) =>
|
metadataValue: (root, { name, machine }) =>
|
||||||
api.machines.metadata
|
api.machines.metadata
|
||||||
.get({ key: name, id: machine })
|
.get({ key: name, id: machine })
|
||||||
.then(value => toKeyValue({ [name]: value }).shift()),
|
.then(value => toKeyValue({ [name]: value }).shift()),
|
||||||
|
|
||||||
tags: (root, { machine, name }) =>
|
tags: (root, { machine, name }) =>
|
||||||
name
|
name
|
||||||
? api.machines.tags
|
? api.machines.tags
|
||||||
.get({ id: machine, tag: name })
|
.get({ id: machine, tag: name })
|
||||||
.then(value => toKeyValue({ [name]: value }))
|
.then(value => toKeyValue({ [name]: value }))
|
||||||
: api.machines.tags.list({ id: machine }).then(toKeyValue),
|
: api.machines.tags.list({ id: machine }).then(toKeyValue),
|
||||||
|
|
||||||
tag: (root, { machine, name }) =>
|
tag: (root, { machine, name }) =>
|
||||||
api.machines.tags
|
api.machines.tags
|
||||||
.get({ id: machine, tag: name })
|
.get({ id: machine, tag: name })
|
||||||
.then(value => toKeyValue({ [name]: value }).shift()),
|
.then(value => toKeyValue({ [name]: value }).shift()),
|
||||||
|
|
||||||
actions: (root, { machine }) => api.machines.audit({ id: machine }),
|
actions: (root, { machine }) => api.machines.audit({ id: machine }),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
firewall_rules: (root, { machine, id }) =>
|
firewall_rules: (root, { machine, id }) =>
|
||||||
id
|
id
|
||||||
@ -88,15 +113,22 @@ const resolvers = {
|
|||||||
: machine
|
: machine
|
||||||
? api.firewall.listByMachine({ id: machine })
|
? api.firewall.listByMachine({ id: machine })
|
||||||
: api.firewall.list(),
|
: api.firewall.list(),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
firewall_rule: (root, { id }) => api.firewall.get({ id }),
|
firewall_rule: (root, { id }) => api.firewall.get({ id }),
|
||||||
|
|
||||||
vlans: (root, { id }) => (id ? api.vlans.get({ id }) : api.vlans.list()),
|
vlans: (root, { id }) => (id ? api.vlans.get({ id }) : api.vlans.list()),
|
||||||
|
|
||||||
vlan: (root, { id }) => api.vlans.get({ id }),
|
vlan: (root, { id }) => api.vlans.get({ id }),
|
||||||
|
|
||||||
networks: (root, { id, vlan }) =>
|
networks: (root, { id, vlan }) =>
|
||||||
id ? api.networks.get({ id, vlan }) : api.networks.list({ vlan }),
|
id ? api.networks.get({ id, vlan }) : api.networks.list({ vlan }),
|
||||||
|
|
||||||
network: (root, { id, vlan }) => api.networks.get({ id, vlan }),
|
network: (root, { id, vlan }) => api.networks.get({ id, vlan }),
|
||||||
|
|
||||||
nics: (root, { machine, mac }) =>
|
nics: (root, { machine, mac }) =>
|
||||||
mac ? api.nics.get({ machine, mac }) : api.nics.list({ machine }),
|
mac ? api.nics.get({ machine, mac }) : api.nics.list({ machine }),
|
||||||
|
|
||||||
nic: (root, { machine, mac }) => api.nics.get({ machine, mac })
|
nic: (root, { machine, mac }) => api.nics.get({ machine, mac })
|
||||||
},
|
},
|
||||||
User: {
|
User: {
|
||||||
@ -104,36 +136,50 @@ const resolvers = {
|
|||||||
},
|
},
|
||||||
Machine: {
|
Machine: {
|
||||||
brand: ({ brand }) => (brand ? brand.toUpperCase() : brand),
|
brand: ({ brand }) => (brand ? brand.toUpperCase() : brand),
|
||||||
|
|
||||||
state: ({ state }) => (state ? state.toUpperCase() : state),
|
state: ({ state }) => (state ? state.toUpperCase() : state),
|
||||||
|
|
||||||
image: ({ image }) => resolvers.Query.image(null, { id: image }),
|
image: ({ image }) => resolvers.Query.image(null, { id: image }),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
primary_ip: ({ primaryIp }) => primaryIp,
|
primary_ip: ({ primaryIp }) => primaryIp,
|
||||||
|
|
||||||
tags: ({ id }, { name }) =>
|
tags: ({ id }, { name }) =>
|
||||||
resolvers.Query.tags(null, { machine: id, name }),
|
resolvers.Query.tags(null, { machine: id, name }),
|
||||||
|
|
||||||
metadata: ({ id }, { name }) =>
|
metadata: ({ id }, { name }) =>
|
||||||
resolvers.Query.metadata(null, { machine: id, name }),
|
resolvers.Query.metadata(null, { machine: id, name }),
|
||||||
|
|
||||||
networks: ({ networks }) =>
|
networks: ({ networks }) =>
|
||||||
Promise.all(networks.map(id => resolvers.Query.network(null, { id }))),
|
Promise.all(networks.map(id => resolvers.Query.network(null, { id }))),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
package: root => resolvers.Query.package(null, { name: root.package }),
|
package: root => resolvers.Query.package(null, { name: root.package }),
|
||||||
|
|
||||||
snapshots: ({ id }, { name }) =>
|
snapshots: ({ id }, { name }) =>
|
||||||
resolvers.Query.snapshots(null, { machine: id, name }),
|
resolvers.Query.snapshots(null, { machine: id, name }),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
firewall_rules: ({ id: machine }, { id }) =>
|
firewall_rules: ({ id: machine }, { id }) =>
|
||||||
resolvers.Query.firewall_rules(null, { machine, id }),
|
resolvers.Query.firewall_rules(null, { machine, id }),
|
||||||
|
|
||||||
actions: ({ id }) => resolvers.Query.actions(null, { machine: id })
|
actions: ({ id }) => resolvers.Query.actions(null, { machine: id })
|
||||||
},
|
},
|
||||||
Image: {
|
Image: {
|
||||||
os: ({ os }) => (os ? os.toUpperCase() : os),
|
os: ({ os }) => (os ? os.toUpperCase() : os),
|
||||||
|
|
||||||
state: ({ state }) => (state ? state.toUpperCase() : state),
|
state: ({ state }) => (state ? state.toUpperCase() : state),
|
||||||
|
|
||||||
type: ({ type }) => (type ? type.toUpperCase() : type)
|
type: ({ type }) => (type ? type.toUpperCase() : type)
|
||||||
},
|
},
|
||||||
Action: {
|
Action: {
|
||||||
name: ({ action }) => action,
|
name: ({ action }) => action,
|
||||||
|
|
||||||
parameters: ({ parameters }) => toKeyValue(parameters)
|
parameters: ({ parameters }) => toKeyValue(parameters)
|
||||||
},
|
},
|
||||||
Caller: {
|
Caller: {
|
||||||
type: ({ type }) => (type ? type.toUpperCase() : type),
|
type: ({ type }) => (type ? type.toUpperCase() : type),
|
||||||
|
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
key_id: ({ keyId }) => keyId
|
key_id: ({ keyId }) => keyId
|
||||||
},
|
},
|
||||||
@ -151,8 +197,39 @@ const resolvers = {
|
|||||||
compression ? compression.toUpperCase() : compression
|
compression ? compression.toUpperCase() : compression
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
|
stopMachine: (root, { id }) =>
|
||||||
|
api.machines.stop(id).then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
|
startMachine: (root, { id }) =>
|
||||||
|
api.machines.start(id).then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
rebootMachine: (root, { id }) =>
|
rebootMachine: (root, { id }) =>
|
||||||
api.machines.reboot(id).then(() => resolvers.Query.machine(null, { id }))
|
api.machines.reboot(id).then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
|
resizeMachine: (root, { id, ...args }) =>
|
||||||
|
api.machines
|
||||||
|
.resize({ id, package: args.package })
|
||||||
|
.then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
|
enableMachineFirewall: (root, { id }) =>
|
||||||
|
api.machines.firewall
|
||||||
|
.enable(id)
|
||||||
|
.then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
|
disableMachineFirewall: (root, { id }) =>
|
||||||
|
api.machines.firewall
|
||||||
|
.disable(id)
|
||||||
|
.then(() => resolvers.Query.machine(null, { id })),
|
||||||
|
|
||||||
|
createMachineSnapshot: (root, { id, name }) =>
|
||||||
|
api.machines.snapshots
|
||||||
|
.create({ id, name })
|
||||||
|
.then(() => resolvers.Query.snapshots(null, { machine: id, name })),
|
||||||
|
|
||||||
|
startMachineFromSnapshot: (root, { id, name }) =>
|
||||||
|
api.machines.snapshots
|
||||||
|
.startFromSnapshot({ id, name })
|
||||||
|
.then(() => resolvers.Query.machine(null, { id }))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"react-styled-flexboxgrid": "^2.0.3",
|
"react-styled-flexboxgrid": "^2.0.3",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
"redux-form": "^7.1.0",
|
"redux-form": "^7.1.1",
|
||||||
"remcalc": "^1.0.9",
|
"remcalc": "^1.0.9",
|
||||||
"styled-components": "^2.2.1",
|
"styled-components": "^2.2.1",
|
||||||
"styled-is": "^1.1.0"
|
"styled-is": "^1.1.0"
|
||||||
@ -51,7 +51,7 @@
|
|||||||
"jest-snapshot": "^21.2.1",
|
"jest-snapshot": "^21.2.1",
|
||||||
"jest-styled-components": "^4.7.0",
|
"jest-styled-components": "^4.7.0",
|
||||||
"jest-transform-graphql": "^2.1.0",
|
"jest-transform-graphql": "^2.1.0",
|
||||||
"joyent-react-scripts": "^2.1.1",
|
"joyent-react-scripts": "^2.2.1",
|
||||||
"react-test-renderer": "^16.0.0",
|
"react-test-renderer": "^16.0.0",
|
||||||
"redrun": "^5.9.18",
|
"redrun": "^5.9.18",
|
||||||
"stylelint": "^8.2.0",
|
"stylelint": "^8.2.0",
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
"redux-actions": "^2.2.1",
|
"redux-actions": "^2.2.1",
|
||||||
"redux-form": "^7.1.0",
|
"redux-form": "^7.1.1",
|
||||||
"remcalc": "^1.0.9",
|
"remcalc": "^1.0.9",
|
||||||
"styled-components": "^2.2.1",
|
"styled-components": "^2.2.1",
|
||||||
"title-case": "^2.1.1"
|
"title-case": "^2.1.1"
|
||||||
@ -57,7 +57,7 @@
|
|||||||
"jest-snapshot": "^21.2.1",
|
"jest-snapshot": "^21.2.1",
|
||||||
"jest-styled-components": "^4.7.0",
|
"jest-styled-components": "^4.7.0",
|
||||||
"jest-transform-graphql": "^2.1.0",
|
"jest-transform-graphql": "^2.1.0",
|
||||||
"joyent-react-scripts": "^2.1.1",
|
"joyent-react-scripts": "^2.2.1",
|
||||||
"react-test-renderer": "^16.0.0",
|
"react-test-renderer": "^16.0.0",
|
||||||
"redrun": "^5.9.18",
|
"redrun": "^5.9.18",
|
||||||
"serve": "^6.2.0",
|
"serve": "^6.2.0",
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import {
|
||||||
|
FormGroup,
|
||||||
|
FormLabel,
|
||||||
|
Input,
|
||||||
|
Button,
|
||||||
|
Message,
|
||||||
|
MessageTitle,
|
||||||
|
MessageDescription
|
||||||
|
} from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
|
export default ({
|
||||||
|
submitting = false,
|
||||||
|
error,
|
||||||
|
handleSubmit = () => {},
|
||||||
|
onCancel = () => {}
|
||||||
|
}) => {
|
||||||
|
const _error = error &&
|
||||||
|
!submitting && (
|
||||||
|
<Message error>
|
||||||
|
<MessageTitle>Ooops!</MessageTitle>
|
||||||
|
<MessageDescription>{error}</MessageDescription>
|
||||||
|
</Message>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
{_error}
|
||||||
|
<FormGroup name="name" reduxForm>
|
||||||
|
<FormLabel>Name (optional)</FormLabel>
|
||||||
|
<Input placeholder="Snapshot name" />
|
||||||
|
</FormGroup>
|
||||||
|
<Button type="button" disabled={submitting} onClick={onCancel} secondary>
|
||||||
|
Back
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" disabled={submitting} loading={submitting}>
|
||||||
|
Create
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
};
|
@ -3,3 +3,5 @@ export { default as List } from './list';
|
|||||||
export { default as KeyValue } from './key-value';
|
export { default as KeyValue } from './key-value';
|
||||||
export { default as Network } from './network';
|
export { default as Network } from './network';
|
||||||
export { default as FirewallRule } from './firewall-rule';
|
export { default as FirewallRule } from './firewall-rule';
|
||||||
|
export { default as Resize } from './resize';
|
||||||
|
export { default as CreateSnapshot } from './create-snapshot';
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Row, Col } from 'react-styled-flexboxgrid';
|
import { Row, Col } from 'react-styled-flexboxgrid';
|
||||||
import forceArray from 'force-array';
|
import forceArray from 'force-array';
|
||||||
|
import get from 'lodash.get';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FormGroup,
|
FormGroup,
|
||||||
@ -14,13 +15,34 @@ import {
|
|||||||
import Item from './item';
|
import Item from './item';
|
||||||
|
|
||||||
export default ({
|
export default ({
|
||||||
instances,
|
instances = [],
|
||||||
|
selected = [],
|
||||||
loading,
|
loading,
|
||||||
handleChange = () => null,
|
handleChange = () => null,
|
||||||
onAction = () => null,
|
onAction = () => null,
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
...rest
|
...rest
|
||||||
}) => {
|
}) => {
|
||||||
|
const allowedActions = {
|
||||||
|
stop: selected.some(({ state }) => state === 'RUNNING'),
|
||||||
|
start: selected.some(({ state }) => state !== 'RUNNING'),
|
||||||
|
reboot: true,
|
||||||
|
resize:
|
||||||
|
selected.length === 1 && selected.every(({ brand }) => brand === 'KVM'),
|
||||||
|
enableFw: selected.some(({ firewall_enabled }) => !firewall_enabled),
|
||||||
|
disableFw: selected.some(({ firewall_enabled }) => firewall_enabled),
|
||||||
|
createSnap: true,
|
||||||
|
startSnap:
|
||||||
|
selected.length === 1 &&
|
||||||
|
selected.every(({ snapshots = [] }) => snapshots.length)
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleActions = ({ target }) =>
|
||||||
|
onAction({
|
||||||
|
name: target.value,
|
||||||
|
items: selected
|
||||||
|
});
|
||||||
|
|
||||||
const _instances = forceArray(instances);
|
const _instances = forceArray(instances);
|
||||||
|
|
||||||
const items = _instances.map((instance, i, all) => (
|
const items = _instances.map((instance, i, all) => (
|
||||||
@ -83,21 +105,46 @@ export default ({
|
|||||||
<FormLabel>⁣</FormLabel>
|
<FormLabel>⁣</FormLabel>
|
||||||
<Select
|
<Select
|
||||||
value="actions"
|
value="actions"
|
||||||
disabled={!items.length}
|
disabled={!items.length || !selected.length}
|
||||||
onChange={({ target }) => onAction(target.value)}
|
onChange={handleActions}
|
||||||
fluid
|
fluid
|
||||||
>
|
>
|
||||||
<option value="actions" selected disabled>
|
<option value="actions" selected disabled>
|
||||||
≡
|
≡
|
||||||
</option>
|
</option>
|
||||||
<option value="stop">Stop</option>
|
<option value="stop" disabled={!allowedActions.stop}>
|
||||||
<option value="start">Start</option>
|
Stop
|
||||||
<option value="reboot">Reboot</option>
|
</option>
|
||||||
<option value="resize">Resize</option>
|
<option value="start" disabled={!allowedActions.start}>
|
||||||
<option value="enable-fw">Enable Firewall</option>
|
Start
|
||||||
<option value="disable-fw">Disable Firewall</option>
|
</option>
|
||||||
<option value="create-snap">Create Snapshot</option>
|
<option value="reboot" disabled={!allowedActions.reboot}>
|
||||||
<option value="start-snap">Start from Snapshot</option>
|
Reboot
|
||||||
|
</option>
|
||||||
|
<option value="resize" disabled={!allowedActions.resize}>
|
||||||
|
Resize
|
||||||
|
</option>
|
||||||
|
<option value="enableFw" disabled={!allowedActions.enableFw}>
|
||||||
|
Enable Firewall
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="disableFw"
|
||||||
|
disabled={!allowedActions.disableFw}
|
||||||
|
>
|
||||||
|
Disable Firewall
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="createSnap"
|
||||||
|
disabled={!allowedActions.createSnap}
|
||||||
|
>
|
||||||
|
Create Snapshot
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
value="startSnap"
|
||||||
|
disabled={!allowedActions.startSnap}
|
||||||
|
>
|
||||||
|
Start from Snapshot
|
||||||
|
</option>
|
||||||
</Select>
|
</Select>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Col>
|
</Col>
|
||||||
|
8
packages/my-joy-beta/src/components/instances/resize.js
Normal file
8
packages/my-joy-beta/src/components/instances/resize.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import ReactJson from 'react-json-view';
|
||||||
|
|
||||||
|
export default ({ instance, packages, handleSubmit }) => (
|
||||||
|
<form onSubmit={handleSubmit}>
|
||||||
|
<ReactJson src={{ instance, packages }} />
|
||||||
|
</form>
|
||||||
|
);
|
@ -0,0 +1,94 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { reduxForm, SubmissionError } from 'redux-form';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { compose, graphql } from 'react-apollo';
|
||||||
|
import find from 'lodash.find';
|
||||||
|
import get from 'lodash.get';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Title,
|
||||||
|
ViewContainer,
|
||||||
|
StatusLoader,
|
||||||
|
Message,
|
||||||
|
MessageTitle,
|
||||||
|
MessageDescription
|
||||||
|
} from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
|
import { CreateSnapshot as InstanceCreateSnapshot } from '@components/instances';
|
||||||
|
import CreateSnapshotMutation from '@graphql/create-snapshot.gql';
|
||||||
|
import GetInstance from '@graphql/get-instance.gql';
|
||||||
|
|
||||||
|
const CreateSnapshot = ({
|
||||||
|
match,
|
||||||
|
instance,
|
||||||
|
loading,
|
||||||
|
error,
|
||||||
|
handleSubmit,
|
||||||
|
handleCancel
|
||||||
|
}) => {
|
||||||
|
const _title = <Title>Create Snapshot</Title>;
|
||||||
|
const _loading = !(loading && !instance) ? null : <StatusLoader />;
|
||||||
|
|
||||||
|
const CreateSnapshotForm = reduxForm({
|
||||||
|
form: `create-snapshot-${match.params.instance}`
|
||||||
|
})(InstanceCreateSnapshot);
|
||||||
|
|
||||||
|
const _error = error &&
|
||||||
|
!instance &&
|
||||||
|
!_loading && (
|
||||||
|
<Message error>
|
||||||
|
<MessageTitle>Ooops!</MessageTitle>
|
||||||
|
<MessageDescription>
|
||||||
|
An error occurred while loading your instance
|
||||||
|
</MessageDescription>
|
||||||
|
</Message>
|
||||||
|
);
|
||||||
|
|
||||||
|
const _form = !loading &&
|
||||||
|
!_error && (
|
||||||
|
<CreateSnapshotForm onSubmit={handleSubmit} onCancel={handleCancel} />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ViewContainer center={Boolean(_loading)} main>
|
||||||
|
{_title}
|
||||||
|
{_loading}
|
||||||
|
{_error}
|
||||||
|
{_form}
|
||||||
|
</ViewContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
graphql(CreateSnapshotMutation, { name: 'createSnapshot' }),
|
||||||
|
graphql(GetInstance, {
|
||||||
|
options: ({ match }) => ({
|
||||||
|
variables: {
|
||||||
|
name: get(match, 'params.instance')
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
props: ({ data: { loading, error, variables, ...rest } }) => ({
|
||||||
|
instance: find(get(rest, 'machines', []), ['name', variables.name]),
|
||||||
|
loading,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
connect(
|
||||||
|
null,
|
||||||
|
(dispatch, { history, location, instance, createSnapshot }) => ({
|
||||||
|
handleCancel: () => history.push(location.pathname.split(/\/\~/).shift()),
|
||||||
|
handleSubmit: ({ name }) =>
|
||||||
|
createSnapshot({
|
||||||
|
variables: { name, id: instance.id }
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
throw new SubmissionError({
|
||||||
|
_error: error.graphQLErrors
|
||||||
|
.map(({ message }) => message)
|
||||||
|
.join('\n')
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(() => history.push(`/instances/${instance.name}/snapshots`))
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)(CreateSnapshot);
|
@ -5,3 +5,5 @@ export { default as Metadata } from './metadata';
|
|||||||
export { default as Networks } from './networks';
|
export { default as Networks } from './networks';
|
||||||
export { default as Firewall } from './firewall';
|
export { default as Firewall } from './firewall';
|
||||||
export { default as Snapshots } from './snapshots';
|
export { default as Snapshots } from './snapshots';
|
||||||
|
export { default as Resize } from './resize';
|
||||||
|
export { default as CreateSnapshot } from './create-snapshot';
|
||||||
|
@ -57,8 +57,6 @@ const List = ({
|
|||||||
</Message>
|
</Message>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
const handleAction = name => onAction({ name, ids: selected });
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ViewContainer main>
|
<ViewContainer main>
|
||||||
{_title}
|
{_title}
|
||||||
@ -66,7 +64,8 @@ const List = ({
|
|||||||
<InstanceListForm
|
<InstanceListForm
|
||||||
instances={_instances}
|
instances={_instances}
|
||||||
loading={loading}
|
loading={loading}
|
||||||
onAction={handleAction}
|
onAction={onAction}
|
||||||
|
selected={selected}
|
||||||
/>
|
/>
|
||||||
</ViewContainer>
|
</ViewContainer>
|
||||||
);
|
);
|
||||||
@ -121,7 +120,8 @@ export default compose(
|
|||||||
const selected = Object.keys(form)
|
const selected = Object.keys(form)
|
||||||
.map(name => find(values, ['name', name]))
|
.map(name => find(values, ['name', name]))
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.map(({ id }) => id);
|
.map(({ id }) => find(instances, ['id', id]))
|
||||||
|
.filter(Boolean);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...rest,
|
...rest,
|
||||||
@ -129,27 +129,39 @@ export default compose(
|
|||||||
selected
|
selected
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
(dispatch, { instances, ...ownProps }) => ({
|
(dispatch, { stop, start, reboot, history, location }) => ({
|
||||||
onAction: ({ name, ids = [] }) => {
|
onAction: ({ name, items = [] }) => {
|
||||||
const types = {
|
const types = {
|
||||||
stop: () =>
|
stop: () =>
|
||||||
Promise.all(ids.map(id => ownProps.stop({ variables: { id } }))),
|
Promise.all(items.map(({ id }) => stop({ variables: { id } }))),
|
||||||
start: () =>
|
start: () =>
|
||||||
Promise.all(ids.map(id => ownProps.start({ variables: { id } }))),
|
Promise.all(items.map(({ id }) => start({ variables: { id } }))),
|
||||||
reboot: () =>
|
reboot: () =>
|
||||||
Promise.all(ids.map(id => ownProps.reboot({ variables: { id } }))),
|
Promise.all(items.map(({ id }) => reboot({ variables: { id } }))),
|
||||||
resize: () => null,
|
resize: () =>
|
||||||
'enable-fw': () => null,
|
Promise.resolve(
|
||||||
'disable-fw': () => null,
|
history.push(`/instances/~resize/${items.shift().name}`)
|
||||||
'create-snap': () => null,
|
),
|
||||||
'start-snap': () => null
|
enableFw: () =>
|
||||||
|
Promise.all(items.map(({ id }) => enableFw({ variables: { id } }))),
|
||||||
|
disableFw: () =>
|
||||||
|
Promise.all(
|
||||||
|
items.map(({ id }) => disableFw({ variables: { id } }))
|
||||||
|
),
|
||||||
|
createSnap: () =>
|
||||||
|
Promise.resolve(
|
||||||
|
history.push(`/instances/~create-snapshot/${items.shift().name}`)
|
||||||
|
),
|
||||||
|
startSnap: () =>
|
||||||
|
Promise.resolve(
|
||||||
|
history.push(`/instances/${items.shift().name}/snapshots`)
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSelected = () =>
|
const clearSelected = () =>
|
||||||
dispatch(
|
dispatch(
|
||||||
ids.map(id => {
|
items.map(({ name: field }) => {
|
||||||
const form = 'instance-list';
|
const form = 'instance-list';
|
||||||
const field = get(find(instances, ['id', id]), 'name');
|
|
||||||
const value = false;
|
const value = false;
|
||||||
|
|
||||||
if (!field) {
|
if (!field) {
|
||||||
|
77
packages/my-joy-beta/src/containers/instances/resize.js
Normal file
77
packages/my-joy-beta/src/containers/instances/resize.js
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { reduxForm } from 'redux-form';
|
||||||
|
import { compose, graphql } from 'react-apollo';
|
||||||
|
import forceArray from 'force-array';
|
||||||
|
import find from 'lodash.find';
|
||||||
|
import get from 'lodash.get';
|
||||||
|
|
||||||
|
import {
|
||||||
|
StatusLoader,
|
||||||
|
Title,
|
||||||
|
ViewContainer,
|
||||||
|
Message,
|
||||||
|
MessageTitle,
|
||||||
|
MessageDescription
|
||||||
|
} from 'joyent-ui-toolkit';
|
||||||
|
|
||||||
|
import { Resize as InstanceResize } from '@components/instances';
|
||||||
|
|
||||||
|
import ListPackages from '@graphql/list-packages.gql';
|
||||||
|
import ListInstances from '@graphql/list-instances.gql';
|
||||||
|
import GetInstance from '@graphql/get-instance.gql';
|
||||||
|
|
||||||
|
const Resize = ({ match, loading, error, instance, packages }) => {
|
||||||
|
const ResizeForm = reduxForm({
|
||||||
|
form: `resize-instance-${match.params.instance}`
|
||||||
|
})(InstanceResize);
|
||||||
|
|
||||||
|
const _packages = forceArray(packages);
|
||||||
|
|
||||||
|
const _title = <Title>Resize</Title>;
|
||||||
|
const _loading = !(loading && (!_packages.length || !instance)) ? null : (
|
||||||
|
<StatusLoader />
|
||||||
|
);
|
||||||
|
|
||||||
|
const _error = !(error && !_loading) ? null : (
|
||||||
|
<Message error>
|
||||||
|
<MessageTitle>Ooops!</MessageTitle>
|
||||||
|
<MessageDescription>An error occurred</MessageDescription>
|
||||||
|
</Message>
|
||||||
|
);
|
||||||
|
|
||||||
|
const _resize =
|
||||||
|
_loading || _error ? null : (
|
||||||
|
<ResizeForm packages={packages} instance={instance} />
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ViewContainer center={Boolean(_loading)} main>
|
||||||
|
{_title}
|
||||||
|
{_loading}
|
||||||
|
{_error}
|
||||||
|
{_resize}
|
||||||
|
</ViewContainer>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default compose(
|
||||||
|
graphql(GetInstance, {
|
||||||
|
options: ({ match }) => ({
|
||||||
|
variables: {
|
||||||
|
name: get(match, 'params.instance')
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
props: ({ data: { loading, error, variables, ...rest } }) => ({
|
||||||
|
instance: find(get(rest, 'machines', []), ['name', variables.name]),
|
||||||
|
loading,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
graphql(ListPackages, {
|
||||||
|
props: ({ data: { packages, loading, error } }) => ({
|
||||||
|
packages: forceArray(packages),
|
||||||
|
loading,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)(Resize);
|
@ -1,3 +1,5 @@
|
|||||||
mutation createInstanceSnapshot($id: ID!, $name: String) {
|
mutation createInstanceSnapshot($id: ID!, $name: String) {
|
||||||
createMachineSnapshot(id: $id, name: $name)
|
createMachineSnapshot(id: $id, name: $name) {
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
query instance($name: String!) {
|
query instance($name: String) {
|
||||||
machines(name: $name) {
|
machines(name: $name) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
@ -8,5 +8,8 @@ query instance($name: String!) {
|
|||||||
created
|
created
|
||||||
updated
|
updated
|
||||||
firewall_enabled
|
firewall_enabled
|
||||||
|
package {
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
packages/my-joy-beta/src/graphql/get-package.gql
Normal file
14
packages/my-joy-beta/src/graphql/get-package.gql
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
query packages($id: ID) {
|
||||||
|
packages(id: $id) {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
memory
|
||||||
|
disk
|
||||||
|
swap
|
||||||
|
lwps
|
||||||
|
vcpus
|
||||||
|
version
|
||||||
|
group
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
@ -13,5 +13,8 @@ query instances {
|
|||||||
package {
|
package {
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
|
snapshots {
|
||||||
|
name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
packages/my-joy-beta/src/graphql/list-packages.gql
Normal file
6
packages/my-joy-beta/src/graphql/list-packages.gql
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
query packages {
|
||||||
|
packages {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
@ -14,32 +14,55 @@ import {
|
|||||||
Metadata as InstanceMetadata,
|
Metadata as InstanceMetadata,
|
||||||
Networks as InstanceNetworks,
|
Networks as InstanceNetworks,
|
||||||
Firewall as InstanceFirewall,
|
Firewall as InstanceFirewall,
|
||||||
Snapshots as InstanceSnapshots
|
Snapshots as InstanceSnapshots,
|
||||||
|
Resize as InstanceResize,
|
||||||
|
CreateSnapshot as InstanceCreateSnapshot
|
||||||
} from '@containers/instances';
|
} from '@containers/instances';
|
||||||
|
|
||||||
export default () => (
|
export default () => (
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<PageContainer>
|
<PageContainer>
|
||||||
|
{/* Header */}
|
||||||
<Route path="*" component={Header} />
|
<Route path="*" component={Header} />
|
||||||
|
|
||||||
|
{/* Breadcrumb */}
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/instances" exact component={Breadcrumb} />
|
<Route
|
||||||
<Route path="/instances/:instance" component={Breadcrumb} />
|
path="/instances/~:action/:instance?"
|
||||||
|
exact
|
||||||
|
component={Breadcrumb}
|
||||||
|
/>
|
||||||
|
<Route path="/instances/:instance?" component={Breadcrumb} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
|
{/* Menu */}
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path="/instances" exact component={Menu} />
|
<Route path="/instances/~:action/:id?" exact component={Menu} />
|
||||||
<Route path="/instances/:instance/:section" component={Menu} />
|
<Route path="/instances/:instance?/:section?" component={Menu} />
|
||||||
</Switch>
|
</Switch>
|
||||||
|
|
||||||
|
{/* Instances List */}
|
||||||
|
<Switch>
|
||||||
<Route path="/instances" exact component={Instances} />
|
<Route path="/instances" exact component={Instances} />
|
||||||
|
</Switch>
|
||||||
|
|
||||||
|
{/* Instance Sections */}
|
||||||
|
<Switch>
|
||||||
|
<Route path="/instances/~:action" component={() => null} />
|
||||||
|
<Route
|
||||||
|
path="/instances/:instance/:section?/~create-snapshot"
|
||||||
|
component={() => null}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/instances/:instance/summary"
|
path="/instances/:instance/summary"
|
||||||
exact
|
exact
|
||||||
component={InstanceSummary}
|
component={InstanceSummary}
|
||||||
/>
|
/>
|
||||||
<Route path="/instances/:instance/tags" exact component={InstanceTags} />
|
<Route
|
||||||
|
path="/instances/:instance/tags"
|
||||||
|
exact
|
||||||
|
component={InstanceTags}
|
||||||
|
/>
|
||||||
<Route
|
<Route
|
||||||
path="/instances/:instance/metadata"
|
path="/instances/:instance/metadata"
|
||||||
exact
|
exact
|
||||||
@ -69,6 +92,31 @@ export default () => (
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
</Switch>
|
||||||
|
|
||||||
|
{/* Actions */}
|
||||||
|
<Switch>
|
||||||
|
<Route
|
||||||
|
path="/instances/~resize/:instance"
|
||||||
|
exact
|
||||||
|
component={InstanceResize}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/instances/:instance/:section?/~resize"
|
||||||
|
exact
|
||||||
|
component={InstanceResize}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/instances/~create-snapshot/:instance"
|
||||||
|
exact
|
||||||
|
component={InstanceCreateSnapshot}
|
||||||
|
/>
|
||||||
|
<Route
|
||||||
|
path="/instances/:instance/:section?/~create-snapshot"
|
||||||
|
exact
|
||||||
|
component={InstanceCreateSnapshot}
|
||||||
|
/>
|
||||||
|
</Switch>
|
||||||
|
|
||||||
<Route path="/" exact component={() => <Redirect to="/instances" />} />
|
<Route path="/" exact component={() => <Redirect to="/instances" />} />
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"react-styled-flexboxgrid": "^2.0.3",
|
"react-styled-flexboxgrid": "^2.0.3",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
"redux-form": "^7.1.0",
|
"redux-form": "^7.1.1",
|
||||||
"remcalc": "^1.0.9",
|
"remcalc": "^1.0.9",
|
||||||
"styled-components": "^2.2.1",
|
"styled-components": "^2.2.1",
|
||||||
"styled-is": "^1.1.0",
|
"styled-is": "^1.1.0",
|
||||||
|
@ -46,17 +46,18 @@
|
|||||||
"disable-scroll": "^0.3.0",
|
"disable-scroll": "^0.3.0",
|
||||||
"file-loader": "^1.1.5",
|
"file-loader": "^1.1.5",
|
||||||
"fontfaceobserver": "^2.0.13",
|
"fontfaceobserver": "^2.0.13",
|
||||||
|
"joy-react-broadcast": "^0.6.9",
|
||||||
"joyent-manifest-editor": "^1.4.0",
|
"joyent-manifest-editor": "^1.4.0",
|
||||||
"lodash.difference": "^4.5.0",
|
"lodash.difference": "^4.5.0",
|
||||||
"lodash.differenceby": "^4.8.0",
|
"lodash.differenceby": "^4.8.0",
|
||||||
"lodash.isequal": "^4.5.0",
|
"lodash.isequal": "^4.5.0",
|
||||||
"lodash.isequalwith": "^4.4.0",
|
"lodash.isequalwith": "^4.4.0",
|
||||||
"lodash.isstring": "^4.0.1",
|
"lodash.isstring": "^4.0.1",
|
||||||
|
"moment": "^2.19.0",
|
||||||
"normalized-styled-components": "^1.0.17",
|
"normalized-styled-components": "^1.0.17",
|
||||||
"pascal-case": "^2.0.1",
|
"pascal-case": "^2.0.1",
|
||||||
"polished": "^1.8.0",
|
"polished": "^1.8.0",
|
||||||
"prop-types": "^15.6.0",
|
"prop-types": "^15.6.0",
|
||||||
"joy-react-broadcast": "^0.6.9",
|
|
||||||
"react-bundle": "^1.0.4",
|
"react-bundle": "^1.0.4",
|
||||||
"react-input-range": "^1.2.1",
|
"react-input-range": "^1.2.1",
|
||||||
"react-responsive": "^2.0.0",
|
"react-responsive": "^2.0.0",
|
||||||
@ -100,10 +101,10 @@
|
|||||||
"react-redux": "^5.0.6",
|
"react-redux": "^5.0.6",
|
||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"react-scripts": "^1.0.14",
|
"react-scripts": "^1.0.14",
|
||||||
"react-styleguidist": "^6.0.28",
|
"react-styleguidist": "^6.0.29",
|
||||||
"react-test-renderer": "^16.0.0",
|
"react-test-renderer": "^16.0.0",
|
||||||
"redux": "^3.7.2",
|
"redux": "^3.7.2",
|
||||||
"redux-form": "^7.1.0",
|
"redux-form": "^7.1.1",
|
||||||
"serve-static": "^1.13.1",
|
"serve-static": "^1.13.1",
|
||||||
"snapguidist": "^2.1.0",
|
"snapguidist": "^2.1.0",
|
||||||
"style-loader": "^0.19.0",
|
"style-loader": "^0.19.0",
|
||||||
@ -121,6 +122,6 @@
|
|||||||
"react": "^16.0.0",
|
"react": "^16.0.0",
|
||||||
"react-dom": "^16.0.0",
|
"react-dom": "^16.0.0",
|
||||||
"react-router-dom": "^4.2.2",
|
"react-router-dom": "^4.2.2",
|
||||||
"redux-form": "^7.1.0"
|
"redux-form": "^7.1.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,13 @@ const style = css`
|
|||||||
`};
|
`};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledAnchor = A.extend`${style};`;
|
const StyledAnchor = A.extend`
|
||||||
|
${style};
|
||||||
|
`;
|
||||||
|
|
||||||
const StyledLink = styled(BaseLink)`${style};`;
|
const StyledLink = styled(BaseLink)`
|
||||||
|
${style};
|
||||||
|
`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @example ./usage.md
|
* @example ./usage.md
|
||||||
|
@ -11,9 +11,19 @@ export const tooltipShadow = `0 ${remcalc(2)} ${remcalc(6)} ${remcalc(
|
|||||||
export const modalShadow = `0 0 ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)`;
|
export const modalShadow = `0 0 ${remcalc(6)} ${remcalc(1)} rgba(0, 0, 0, 0.1)`;
|
||||||
|
|
||||||
export const border = {
|
export const border = {
|
||||||
checked: css`${remcalc(1)} solid ${props => props.theme.primary};`,
|
checked: css`
|
||||||
unchecked: css`${remcalc(1)} solid ${props => props.theme.grey};`,
|
${remcalc(1)} solid ${props => props.theme.primary};
|
||||||
confirmed: css`${remcalc(1)} solid ${props => props.theme.grey};`,
|
`,
|
||||||
error: css`${remcalc(1)} solid ${props => props.theme.red};`,
|
unchecked: css`
|
||||||
secondary: css`${remcalc(1)} solid ${props => props.theme.secondaryActive};`
|
${remcalc(1)} solid ${props => props.theme.grey};
|
||||||
|
`,
|
||||||
|
confirmed: css`
|
||||||
|
${remcalc(1)} solid ${props => props.theme.grey};
|
||||||
|
`,
|
||||||
|
error: css`
|
||||||
|
${remcalc(1)} solid ${props => props.theme.red};
|
||||||
|
`,
|
||||||
|
secondary: css`
|
||||||
|
${remcalc(1)} solid ${props => props.theme.secondaryActive};
|
||||||
|
`
|
||||||
};
|
};
|
||||||
|
@ -61,12 +61,9 @@ const GraphNodeInfo = ({ data, pos }) => {
|
|||||||
const healthy = (
|
const healthy = (
|
||||||
<HealthyIcon
|
<HealthyIcon
|
||||||
healthy={
|
healthy={
|
||||||
instancesHealthy &&
|
instancesHealthy && instancesHealthy.total === instancesHealthy.healthy
|
||||||
instancesHealthy.total === instancesHealthy.healthy ? (
|
? 'HEALTHY'
|
||||||
'HEALTHY'
|
: 'UNHEALTHY'
|
||||||
) : (
|
|
||||||
'UNHEALTHY'
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
32
yarn.lock
32
yarn.lock
@ -392,7 +392,7 @@ apollo-server-core@^1.1.6:
|
|||||||
dependencies:
|
dependencies:
|
||||||
apollo-tracing "^0.0.7"
|
apollo-tracing "^0.0.7"
|
||||||
|
|
||||||
apollo-server-hapi@^1.1.3:
|
apollo-server-hapi@^1.1.6:
|
||||||
version "1.1.6"
|
version "1.1.6"
|
||||||
resolved "https://registry.yarnpkg.com/apollo-server-hapi/-/apollo-server-hapi-1.1.6.tgz#97bdc483afe908e28aa0ae9a3ee7744d581bc3bf"
|
resolved "https://registry.yarnpkg.com/apollo-server-hapi/-/apollo-server-hapi-1.1.6.tgz#97bdc483afe908e28aa0ae9a3ee7744d581bc3bf"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -1767,7 +1767,7 @@ babel-preset-jest@^21.2.0:
|
|||||||
babel-plugin-jest-hoist "^21.2.0"
|
babel-plugin-jest-hoist "^21.2.0"
|
||||||
babel-plugin-syntax-object-rest-spread "^6.13.0"
|
babel-plugin-syntax-object-rest-spread "^6.13.0"
|
||||||
|
|
||||||
babel-preset-joyent-portal@^3.0.1:
|
babel-preset-joyent-portal@^3.1.0:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-preset-joyent-portal/-/babel-preset-joyent-portal-3.2.0.tgz#0801746916568886beba5c2911ce1c55ec142320"
|
resolved "https://registry.yarnpkg.com/babel-preset-joyent-portal/-/babel-preset-joyent-portal-3.2.0.tgz#0801746916568886beba5c2911ce1c55ec142320"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4363,11 +4363,7 @@ escope@^3.6.0:
|
|||||||
esrecurse "^4.1.0"
|
esrecurse "^4.1.0"
|
||||||
estraverse "^4.1.1"
|
estraverse "^4.1.1"
|
||||||
|
|
||||||
eslint-config-joyent-portal@3.0.0:
|
eslint-config-joyent-portal@3.1.0, eslint-config-joyent-portal@^3.0.0:
|
||||||
version "3.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-joyent-portal/-/eslint-config-joyent-portal-3.0.0.tgz#269e3e0b88abba96adc3a6dc0bbf604a6ae89356"
|
|
||||||
|
|
||||||
eslint-config-joyent-portal@^3.0.0:
|
|
||||||
version "3.1.0"
|
version "3.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/eslint-config-joyent-portal/-/eslint-config-joyent-portal-3.1.0.tgz#7a77270d118627e59461db29d35639cf146d1dfc"
|
resolved "https://registry.yarnpkg.com/eslint-config-joyent-portal/-/eslint-config-joyent-portal-3.1.0.tgz#7a77270d118627e59461db29d35639cf146d1dfc"
|
||||||
|
|
||||||
@ -5832,7 +5828,7 @@ graphql-tools@^1.1.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
"@types/graphql" "^0.9.0"
|
"@types/graphql" "^0.9.0"
|
||||||
|
|
||||||
graphql-tools@^2.2.1:
|
graphql-tools@^2.3.0:
|
||||||
version "2.4.0"
|
version "2.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-2.4.0.tgz#183d7e509e1ebd07d51db05fdeb181e7126f7ecb"
|
resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-2.4.0.tgz#183d7e509e1ebd07d51db05fdeb181e7126f7ecb"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7492,7 +7488,7 @@ joy-react-broadcast@^0.6.9:
|
|||||||
prop-types "^15.5.6"
|
prop-types "^15.5.6"
|
||||||
warning "^3.0.0"
|
warning "^3.0.0"
|
||||||
|
|
||||||
joyent-manifest-editor@^1.3.0:
|
joyent-manifest-editor@^1.4.0:
|
||||||
version "1.4.0"
|
version "1.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/joyent-manifest-editor/-/joyent-manifest-editor-1.4.0.tgz#0c02efe6c02b0386a5b209ae4ddcc3492b9c22ac"
|
resolved "https://registry.yarnpkg.com/joyent-manifest-editor/-/joyent-manifest-editor-1.4.0.tgz#0c02efe6c02b0386a5b209ae4ddcc3492b9c22ac"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -7500,7 +7496,7 @@ joyent-manifest-editor@^1.3.0:
|
|||||||
prop-types "^15.6.0"
|
prop-types "^15.6.0"
|
||||||
react-codemirror "^1.0.0"
|
react-codemirror "^1.0.0"
|
||||||
|
|
||||||
joyent-react-scripts@^2.0.2:
|
joyent-react-scripts@^2.2.1:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/joyent-react-scripts/-/joyent-react-scripts-2.3.0.tgz#9e48f93d67284b8149dc73b35ccdfc11d27131d9"
|
resolved "https://registry.yarnpkg.com/joyent-react-scripts/-/joyent-react-scripts-2.3.0.tgz#9e48f93d67284b8149dc73b35ccdfc11d27131d9"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -8913,7 +8909,7 @@ normalize-url@^1.4.0:
|
|||||||
query-string "^4.1.0"
|
query-string "^4.1.0"
|
||||||
sort-keys "^1.0.0"
|
sort-keys "^1.0.0"
|
||||||
|
|
||||||
normalized-styled-components@^1.0.14:
|
normalized-styled-components@^1.0.17:
|
||||||
version "1.0.17"
|
version "1.0.17"
|
||||||
resolved "https://registry.yarnpkg.com/normalized-styled-components/-/normalized-styled-components-1.0.17.tgz#fd3a82e00b87d0c89d973f795cdaa7b5025ebb8a"
|
resolved "https://registry.yarnpkg.com/normalized-styled-components/-/normalized-styled-components-1.0.17.tgz#fd3a82e00b87d0c89d973f795cdaa7b5025ebb8a"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10462,7 +10458,7 @@ react-styled-flexboxgrid@^2.0.3:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash.isinteger "^4.0.4"
|
lodash.isinteger "^4.0.4"
|
||||||
|
|
||||||
react-styleguidist@^6.0.28:
|
react-styleguidist@^6.0.29:
|
||||||
version "6.0.30"
|
version "6.0.30"
|
||||||
resolved "https://registry.yarnpkg.com/react-styleguidist/-/react-styleguidist-6.0.30.tgz#988a09282f8af43749e44602349ec524dc1f07a0"
|
resolved "https://registry.yarnpkg.com/react-styleguidist/-/react-styleguidist-6.0.30.tgz#988a09282f8af43749e44602349ec524dc1f07a0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10780,7 +10776,7 @@ reduce-css-calc@^1.2.6:
|
|||||||
math-expression-evaluator "^1.2.14"
|
math-expression-evaluator "^1.2.14"
|
||||||
reduce-function-call "^1.0.1"
|
reduce-function-call "^1.0.1"
|
||||||
|
|
||||||
reduce-css-calc@^2.0.5:
|
reduce-css-calc@^2.1.0:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.1.tgz#f4ecd7a00ec3e5683773f208067ad7da117b9db0"
|
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.1.tgz#f4ecd7a00ec3e5683773f208067ad7da117b9db0"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -10806,7 +10802,7 @@ redux-actions@^2.2.1:
|
|||||||
lodash-es "^4.17.4"
|
lodash-es "^4.17.4"
|
||||||
reduce-reducers "^0.1.0"
|
reduce-reducers "^0.1.0"
|
||||||
|
|
||||||
redux-form@^7.1.0:
|
redux-form@^7.1.1:
|
||||||
version "7.1.1"
|
version "7.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-7.1.1.tgz#4d9ab1d9c03beb3a8b5f8e5d0f398cff4209081f"
|
resolved "https://registry.yarnpkg.com/redux-form/-/redux-form-7.1.1.tgz#4d9ab1d9c03beb3a8b5f8e5d0f398cff4209081f"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -11375,7 +11371,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
|||||||
hash-base "^2.0.0"
|
hash-base "^2.0.0"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
|
|
||||||
rnd-id@^1.0.8:
|
rnd-id@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/rnd-id/-/rnd-id-1.1.1.tgz#aaa11c650cf4105eeb1025eecf185db89071afb6"
|
resolved "https://registry.yarnpkg.com/rnd-id/-/rnd-id-1.1.1.tgz#aaa11c650cf4105eeb1025eecf185db89071afb6"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -12225,11 +12221,11 @@ styled-components@^2.2.1:
|
|||||||
stylis "^3.2.1"
|
stylis "^3.2.1"
|
||||||
supports-color "^3.2.3"
|
supports-color "^3.2.3"
|
||||||
|
|
||||||
styled-is@^1.0.15:
|
styled-is@^1.1.0:
|
||||||
version "1.1.0"
|
version "1.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/styled-is/-/styled-is-1.1.0.tgz#0cf8d32098fe6559eb0ec889790cc6c84f1f497f"
|
resolved "https://registry.yarnpkg.com/styled-is/-/styled-is-1.1.0.tgz#0cf8d32098fe6559eb0ec889790cc6c84f1f497f"
|
||||||
|
|
||||||
stylelint-config-joyent-portal@^2.0.0:
|
stylelint-config-joyent-portal@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/stylelint-config-joyent-portal/-/stylelint-config-joyent-portal-2.0.1.tgz#9d9242807749db394b9b9c3da7bc48b9b818a16e"
|
resolved "https://registry.yarnpkg.com/stylelint-config-joyent-portal/-/stylelint-config-joyent-portal-2.0.1.tgz#9d9242807749db394b9b9c3da7bc48b9b818a16e"
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -13019,7 +13015,7 @@ unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.1.3:
|
|||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.3.tgz#ec268e731b9d277a79a5b5aa0643990e405d600b"
|
resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.1.3.tgz#ec268e731b9d277a79a5b5aa0643990e405d600b"
|
||||||
|
|
||||||
unitcalc@^1.1.0:
|
unitcalc@^1.1.1:
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/unitcalc/-/unitcalc-1.1.1.tgz#a57e1c9dd61f251d2fad0c1d19f8577255cf080a"
|
resolved "https://registry.yarnpkg.com/unitcalc/-/unitcalc-1.1.1.tgz#a57e1c9dd61f251d2fad0c1d19f8577255cf080a"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user