diff --git a/packages/images/src/components/image.js b/packages/images/src/components/image.js index 8bf9ae23..7e9278ef 100644 --- a/packages/images/src/components/image.js +++ b/packages/images/src/components/image.js @@ -3,7 +3,7 @@ import { Link } from 'react-router-dom'; import styled from 'styled-components'; import remcalc from 'remcalc'; import { Field } from 'redux-form'; -import Flex, { FlexItem } from 'styled-flex-component'; +import Flex from 'styled-flex-component'; import { Padding, Margin } from 'styled-components-spacing'; import { @@ -19,7 +19,8 @@ import { PopoverContainer, Radio, FormLabel, - FormGroup + FormGroup, + StatusLoader } from 'joyent-ui-toolkit'; import { ImageType, OS } from '@root/constants'; @@ -61,54 +62,71 @@ const Actions = styled(Flex)` min-width: 48px; `; -export const Image = ({ name, os, version, type }) => ( +export const Image = ({ name, os, version, type, removing, onRemove }) => ( - - - - - {React.createElement(OS[os], { - width: '24', - height: '24' - })} - - - {name} - - + {removing ? ( + + - - - - - - {version} - - - - {ImageType[type]} - - - - - - - - - - {}}> - Create Instance - - - {}}> - Remove - - - - - + ) : ( + + + + + + {React.createElement(OS[os], { + width: '24', + height: '24' + })} + + + {name} + + + + + + + + + {version} + + + + {ImageType[type]} + + + + + + + + + + + + Create Instance + + + + + Remove + + + + + + + )} diff --git a/packages/images/src/components/summary.js b/packages/images/src/components/summary.js index 7c9b7f8a..969b45e3 100644 --- a/packages/images/src/components/summary.js +++ b/packages/images/src/components/summary.js @@ -98,7 +98,7 @@ export const Meta = ({ name, version, type, published_at, state, os }) => ( ); -export default withTheme(({ theme = {}, ...image }) => ( +export default withTheme(({ theme = {}, onRemove, removing, ...image }) => ( @@ -113,7 +113,12 @@ export default withTheme(({ theme = {}, ...image }) => ( - @@ -126,7 +131,15 @@ export default withTheme(({ theme = {}, ...image }) => ( - diff --git a/packages/images/src/containers/create.js b/packages/images/src/containers/create.js index 11f62a93..46f8ab02 100644 --- a/packages/images/src/containers/create.js +++ b/packages/images/src/containers/create.js @@ -112,35 +112,23 @@ export default compose( } }), connect(({ form, values }, { match }) => { - const nameFilled = get(form, `${Forms.FORM_DETAILS}.values.name`, ''); const step = get(match, 'params.step', 'name'); - const disabled = - !get(values, `${Forms.FORM_DETAILS}-proceeded`, false) || - !nameFilled.length; + const name = get(form, `${Forms.FORM_DETAILS}.values.name`, ''); + const version = get(form, `${Forms.FORM_DETAILS}.values.version`, ''); + + const disabled = !(name.length && version.length); if (disabled) { return { disabled, step }; } - const name = get( - form, - `${Forms.FORM_DETAILS}.values.name`, - '' - ); - const description = get( form, `${Forms.FORM_DETAILS}.values.description`, '' ); - const version = get( - form, - `${Forms.FORM_DETAILS}.values.version`, - '' - ); - const tags = get(values, Forms.CREATE_TAGS, []); return { diff --git a/packages/images/src/containers/list.js b/packages/images/src/containers/list.js index cbd7188b..73d594a4 100644 --- a/packages/images/src/containers/list.js +++ b/packages/images/src/containers/list.js @@ -8,6 +8,8 @@ import { connect } from 'react-redux'; import get from 'lodash.get'; import find from 'lodash.find'; import Index from '@state/gen-index'; +import intercept from 'apr-intercept'; +import { set } from 'react-redux-values'; import { ViewContainer, @@ -23,6 +25,8 @@ import Empty from '@components/empty'; import { ImageType } from '@root/constants'; import ListImages from '@graphql/list-images.gql'; import { Image, Filters } from '@components/image'; +import RemoveImage from '@graphql/remove-image.gql'; +import parseError from '@state/parse-error'; const TOGGLE_FORM_DETAILS = 'images-list-toggle'; const MENU_FORM_DETAILS = 'images-list-menu'; @@ -33,7 +37,8 @@ export const List = ({ loading = false, error = null, history, - typeValue + typeValue, + handleRemove }) => ( @@ -72,9 +77,9 @@ export const List = ({ - {images.map(image => ( + {images.map((image) => ( - + handleRemove(image.id)} /> ))} {!images.length && !loading ? ( @@ -86,7 +91,9 @@ export const List = ({ ); export default compose( + graphql(RemoveImage, { name: 'removeImage' }), graphql(ListImages, { + options: { pollInterval: 5000 }, props: ({ data: { images, loading, error, refetch } }) => { return { images, @@ -95,42 +102,77 @@ export default compose( }; } }), - connect(({ form, values }, { index, error, images = [] }) => { - const filter = get(form, `${MENU_FORM_DETAILS}.values.filter`, false); - const typeValue = get( - form, - `${TOGGLE_FORM_DETAILS}.values.image-type`, - 'all' - ); + connect( + ({ form, values }, { index, error, images = [] }) => { + const filter = get(form, `${MENU_FORM_DETAILS}.values.filter`, false); + const mutationError = get(values, 'remove-mutation-error', null); - const virtual = Object.keys(ImageType).filter( - i => ImageType[i] === 'Hardware Virtual Machine' - ); - const container = Object.keys(ImageType).filter( - i => ImageType[i] === 'Infrastructure Container' - ); + const typeValue = get( + form, + `${TOGGLE_FORM_DETAILS}.values.image-type`, + 'all' + ); - const filtered = filter - ? Index(images) - .search(filter) - .map(({ ref }) => find(images, ['id', ref])) - : images; + const virtual = Object.keys(ImageType).filter( + i => ImageType[i] === 'Hardware Virtual Machine' + ); - return { - images: filtered.filter(image => { - switch (typeValue) { - case 'all': - return true; - case 'hardware-virtual-machine': - return virtual.includes(image.type); - case 'infrastructure-container': - return container.includes(image.type); - default: - return true; + const container = Object.keys(ImageType).filter( + i => ImageType[i] === 'Infrastructure Container' + ); + + const filtered = filter + ? Index(images) + .search(filter) + .map(({ ref }) => find(images, ['id', ref])) + : images; + + return { + images: filtered.filter(image => { + switch (typeValue) { + case 'all': + return true; + case 'hardware-virtual-machine': + return virtual.includes(image.type); + case 'infrastructure-container': + return container.includes(image.type); + default: + return true; + } + }).map(({ id, ...image }) => ({ + ...image, + id, + removing: get(values, `remove-mutation-${id}-loading`, false) + })), + allImages: images, + mutationError, + typeValue + }; + }, + (dispatch, { removeImage, history }) => ({ + handleRemove: async id => { + dispatch([set({ name: `remove-mutation-${id}-loading`, value: true })]); + + const [err, res] = await intercept( + removeImage({ + variables: { + id + } + }) + ); + + if (err) { + dispatch([ + set({ name: 'remove-mutation-error', value: parseError(err) }), + set({ name: `remove-mutation-${id}-loading`, value: false }) + ]); } - }), - allImages: images, - typeValue - }; - }) + + if (res) { + dispatch([set({ name: `remove-mutation-${id}-loading`, value: false })]); + history.push(`/`); + } + } + }) + ) )(List); diff --git a/packages/images/src/containers/summary.js b/packages/images/src/containers/summary.js index 57199fac..d2d0d69d 100644 --- a/packages/images/src/containers/summary.js +++ b/packages/images/src/containers/summary.js @@ -4,6 +4,9 @@ import { Margin } from 'styled-components-spacing'; import find from 'lodash.find'; import get from 'lodash.get'; import remcalc from 'remcalc'; +import { connect } from 'react-redux'; +import intercept from 'apr-intercept'; +import { set } from 'react-redux-values'; import { ViewContainer, @@ -16,8 +19,17 @@ import { import ImageSummary from '@components/summary'; import GetImage from '@graphql/get-image.gql'; +import RemoveImage from '@graphql/remove-image.gql'; +import parseError from '@state/parse-error'; -export const Summary = ({ image, loading = false, error = null }) => ( +export const Summary = ({ + image, + loading = false, + error = null, + removing, + mutationError, + handleRemove +}) => ( {loading && !image ? ( @@ -35,11 +47,24 @@ export const Summary = ({ image, loading = false, error = null }) => ( ) : null} - {image ? : null} + {mutationError ? ( + + + Ooops! + + There was a problem deleting your image + + + + ) : null} + {image ? ( + + ) : null} ); export default compose( + graphql(RemoveImage, { name: 'removeImage' }), graphql(GetImage, { options: ({ match }) => ({ variables: { @@ -53,5 +78,42 @@ export default compose( loading, error }) - }) + }), + connect( + ({ values }, ownProps) => { + const removing = get(values, 'remove-mutation-loading', false); + const mutationError = get(values, 'remove-mutation-error', null); + + return { + ...ownProps, + removing, + mutationError + }; + }, + (dispatch, { removeImage, image, history }) => ({ + handleRemove: async () => { + dispatch([set({ name: 'remove-mutation-loading', value: true })]); + + const [err, res] = await intercept( + removeImage({ + variables: { + id: image.id + } + }) + ); + + if (err) { + dispatch([ + set({ name: 'remove-mutation-error', value: parseError(err) }), + set({ name: 'remove-mutation-loading', value: false }) + ]); + } + + if (res) { + dispatch([set({ name: 'remove-mutation-loading', value: false })]); + history.push(`/`); + } + } + }) + ) )(Summary); diff --git a/packages/images/src/graphql/remove-image.gql b/packages/images/src/graphql/remove-image.gql new file mode 100644 index 00000000..a676e297 --- /dev/null +++ b/packages/images/src/graphql/remove-image.gql @@ -0,0 +1,6 @@ +mutation removeImage($id: ID!) { + deleteImage(id: $id) { + id + name + } +} diff --git a/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/key-value-ui-js-key-value-submitting-1-snap.png b/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/key-value-ui-js-key-value-submitting-1-snap.png index e00af188..e742a1c1 100644 Binary files a/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/key-value-ui-js-key-value-submitting-1-snap.png and b/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/key-value-ui-js-key-value-submitting-1-snap.png differ diff --git a/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/network-ui-js-network-network-public-3-snap.png b/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/network-ui-js-network-network-public-3-snap.png new file mode 100644 index 00000000..f0a23cfc Binary files /dev/null and b/packages/my-joy-beta/src/components/__tests__/__image_snapshots__/network-ui-js-network-network-public-3-snap.png differ diff --git a/packages/my-joy-beta/src/components/create-instance/__tests__/__image_snapshots__/images-ui-js-images-images-name-stuff-image-name-stuff-1-snap.png b/packages/my-joy-beta/src/components/create-instance/__tests__/__image_snapshots__/images-ui-js-images-images-name-stuff-image-name-stuff-1-snap.png index bbed2669..d340b338 100644 Binary files a/packages/my-joy-beta/src/components/create-instance/__tests__/__image_snapshots__/images-ui-js-images-images-name-stuff-image-name-stuff-1-snap.png and b/packages/my-joy-beta/src/components/create-instance/__tests__/__image_snapshots__/images-ui-js-images-images-name-stuff-image-name-stuff-1-snap.png differ diff --git a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/list-ui-js-item-mutating-1-snap.png b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/list-ui-js-item-mutating-1-snap.png index 87bf4404..d2e4fdea 100644 Binary files a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/list-ui-js-item-mutating-1-snap.png and b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/list-ui-js-item-mutating-1-snap.png differ diff --git a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/snapshots-ui-js-item-mutating-1-snap.png b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/snapshots-ui-js-item-mutating-1-snap.png index 021d6e23..b19e8e3d 100644 Binary files a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/snapshots-ui-js-item-mutating-1-snap.png and b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/snapshots-ui-js-item-mutating-1-snap.png differ diff --git a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/summary-ui-js-summary-starting-stopping-rebooting-removing-1-snap.png b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/summary-ui-js-summary-starting-stopping-rebooting-removing-1-snap.png index 2d1a67f7..79d89696 100644 Binary files a/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/summary-ui-js-summary-starting-stopping-rebooting-removing-1-snap.png and b/packages/my-joy-beta/src/components/instances/__tests__/__image_snapshots__/summary-ui-js-summary-starting-stopping-rebooting-removing-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/create-instance/__tests__/__image_snapshots__/networks-ui-js-networks-loading-expanded-1-snap.png b/packages/my-joy-beta/src/containers/create-instance/__tests__/__image_snapshots__/networks-ui-js-networks-loading-expanded-1-snap.png index 2e0e3f25..9c3d0b79 100644 Binary files a/packages/my-joy-beta/src/containers/create-instance/__tests__/__image_snapshots__/networks-ui-js-networks-loading-expanded-1-snap.png and b/packages/my-joy-beta/src/containers/create-instance/__tests__/__image_snapshots__/networks-ui-js-networks-loading-expanded-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/cns-ui-js-cns-loading-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/cns-ui-js-cns-loading-1-snap.png index fa5cad51..92b6af88 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/cns-ui-js-cns-loading-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/cns-ui-js-cns-loading-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/firewall-ui-js-firewall-loading-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/firewall-ui-js-firewall-loading-1-snap.png index 46eb4802..b8185b68 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/firewall-ui-js-firewall-loading-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/firewall-ui-js-firewall-loading-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/list-ui-js-list-loading-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/list-ui-js-list-loading-1-snap.png index 75b9d3c9..1b5fa345 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/list-ui-js-list-loading-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/list-ui-js-list-loading-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/metadata-ui-js-metadata-metadata-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/metadata-ui-js-metadata-metadata-1-snap.png index fdbfa404..56ae4c34 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/metadata-ui-js-metadata-metadata-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/metadata-ui-js-metadata-metadata-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-1-snap.png index a141971c..217b0c57 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-loading-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-loading-1-snap.png index 6065dfa6..29443b7b 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-loading-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-loading-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-mutation-error-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-mutation-error-1-snap.png index c672f70e..31737473 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-mutation-error-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/summary-ui-js-summary-mutation-error-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-editing-removing-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-editing-removing-1-snap.png index 09e78716..8e406260 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-editing-removing-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-editing-removing-1-snap.png differ diff --git a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-loading-1-snap.png b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-loading-1-snap.png index c6572d25..2811b683 100644 Binary files a/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-loading-1-snap.png and b/packages/my-joy-beta/src/containers/instances/__tests__/__image_snapshots__/tags-ui-js-tags-loading-1-snap.png differ diff --git a/packages/my-joy-beta/src/router.js b/packages/my-joy-beta/src/router.js index 5ac3adb1..8713d0ea 100644 --- a/packages/my-joy-beta/src/router.js +++ b/packages/my-joy-beta/src/router.js @@ -82,11 +82,7 @@ export default () => ( exact component={InstanceSnapshots} /> - +