From 397ceff8339e9a91dfaff1edea4f42966c7e3449 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Nov 2018 18:28:11 -0500 Subject: [PATCH] push uri list now works --- assets/js/actions/targets.js | 47 ++++++++++++++++++++++++ assets/js/components/UnderlineInput.js | 9 +++-- assets/js/containers/UriListItem.js | 16 +++++++- assets/js/lib/Ajax.js | 2 +- assets/js/reducers/targets.js | 19 +++++++++- assets/js/targets.js | 12 +++++- assets/styles/shared/underlineinput.scss | 5 ++- assets/styles/shared/urilistitem.scss | 12 ++---- assets/styles/targets.scss | 21 ++++++++++- 9 files changed, 123 insertions(+), 20 deletions(-) diff --git a/assets/js/actions/targets.js b/assets/js/actions/targets.js index 8e60e7c..bc68fd7 100644 --- a/assets/js/actions/targets.js +++ b/assets/js/actions/targets.js @@ -28,6 +28,34 @@ export const addUrl = url => ({ data: url }) +export const changeUrlField = (id, value) => ({ + type: ACTIONS.edit_url, + data: { + id, + value + } +}) + +export const removeUrl = id => async (dispatch, getState) => { + dispatch(setWorking(true)) + try { + await Ajax.delete({ + url: '/api/targets/' + id + }) + dispatch({ + type: ACTIONS.delete_url, + data: id + }) + } catch (e) { + dispatch({ + type: ACTIONS.error, + data: e + }) + } finally { + dispatch(setWorking(false)) + } +} + export const fetchUrls = () => async (dispatch, getState) => { dispatch(setWorking(true)) try { @@ -61,3 +89,22 @@ export const createNewUrl = () => async (dispatch, getState) => { dispatch(setWorking(false)) } } + +export const setUrl = (id, value) => async (dispatch, getState) => { + dispatch(setWorking(true)) + try { + await Ajax.patch({ + url: '/api/targets/' + id, + data: { + url: value + } + }) + } catch (e) { + dispatch({ + type: ACTIONS.error, + data: e + }) + } finally { + dispatch(setWorking(false)) + } +} diff --git a/assets/js/components/UnderlineInput.js b/assets/js/components/UnderlineInput.js index 2a5aeda..b1b7a90 100644 --- a/assets/js/components/UnderlineInput.js +++ b/assets/js/components/UnderlineInput.js @@ -5,14 +5,17 @@ import React from 'react' import '../../styles/shared/underlineinput.scss' const UnderlineInput = props => ( -
+
+ onChange={props.onChange} + onBlur={props.onBlur} />
diff --git a/assets/js/containers/UriListItem.js b/assets/js/containers/UriListItem.js index 8407eac..932ba4d 100644 --- a/assets/js/containers/UriListItem.js +++ b/assets/js/containers/UriListItem.js @@ -2,7 +2,11 @@ import React from 'react' import IconButton from '../components/IconButton' +import UnderlineInput from '../components/UnderlineInput' import '../../styles/shared/urilistitem.scss' +import { changeUrlField, setUrl, removeUrl } from '../actions/targets' + +const uriRegex = /(.+:\/\/)?(.+\.)*(.+\.).{1,}(:\d+)?(.+)?/i class UriListItem extends React.Component { constructor () { @@ -11,8 +15,16 @@ class UriListItem extends React.Component { render () { return (
  • - uri.uri - + this.props.dispatch(changeUrlField(this.props.id, e.target.value))} + onBlur={(e) => this.props.dispatch(setUrl(this.props.id, e.target.value))} /> + this.props.dispatch(removeUrl(this.props.id))}/>
  • ) } diff --git a/assets/js/lib/Ajax.js b/assets/js/lib/Ajax.js index f7b9305..09bc05f 100644 --- a/assets/js/lib/Ajax.js +++ b/assets/js/lib/Ajax.js @@ -81,7 +81,7 @@ export default class Ajax { } xhr.onload = () => { - if (xhr.status !== 200) { return xhr.onerror() } + if (!('' + xhr.status).startsWith('2')) { return xhr.onerror() } var data = xhr.response try { data = JSON.parse(data) diff --git a/assets/js/reducers/targets.js b/assets/js/reducers/targets.js index b48b1f3..fd028ab 100644 --- a/assets/js/reducers/targets.js +++ b/assets/js/reducers/targets.js @@ -4,6 +4,7 @@ import Actions from '../actions/targets' const reducer = (state = {}, action) => { const { type, data } = action + let urls switch (type) { case Actions.set_working: return { @@ -15,7 +16,23 @@ const reducer = (state = {}, action) => { } case Actions.add_url: return { - urls: state.urls.concat(data) + urls: state.urls.concat(data), + error: '' + } + case Actions.delete_url: + return { + urls: state.urls.filter(x => x.id !== data), + error: '' + } + case Actions.edit_url: + urls = state.urls + urls.find(x => x.id === data.id).url = data.value + return { + urls: urls + } + case Actions.error: + return { + error: data.message } default: return {} } diff --git a/assets/js/targets.js b/assets/js/targets.js index 11c74b8..4613c14 100644 --- a/assets/js/targets.js +++ b/assets/js/targets.js @@ -17,7 +17,10 @@ class App extends React.Component { email: '', password: '' }, - urls: [1, 2], + urls: [{ + id: 1, + url: 'http' + }], working: false } @@ -41,7 +44,11 @@ class App extends React.Component { } getRegisteredUris () { return this.state.urls.map((item, i) => { - return () + return () }) } render () { @@ -54,6 +61,7 @@ class App extends React.Component {
    + {this.state.error &&
    {this.state.error}
    }

    Push URIs

    diff --git a/assets/styles/shared/underlineinput.scss b/assets/styles/shared/underlineinput.scss index 0723490..589ffda 100644 --- a/assets/styles/shared/underlineinput.scss +++ b/assets/styles/shared/underlineinput.scss @@ -71,6 +71,9 @@ left: 0; } } + &.invalid { + color: $red; + } &.invalid:focus + .reacts-to, &.invalid:active + .reacts-to, &.invalid.has-content + .reacts-to { @@ -79,7 +82,7 @@ } } &.invalid + .reacts-to { - .underline { + .underline:before { background: $red; } } diff --git a/assets/styles/shared/urilistitem.scss b/assets/styles/shared/urilistitem.scss index 6d84e8c..2f6f8c3 100644 --- a/assets/styles/shared/urilistitem.scss +++ b/assets/styles/shared/urilistitem.scss @@ -1,16 +1,12 @@ @import '../lib/vars'; .uri-list-item { - height: 50px; - line-height: 50px; + height: 60px; + line-height: 60px; background: $background-1; box-shadow: $shadow-0; - .uri { - display: inline-block; - font-size: 16px; - } & > .button.icon { - margin: 5px; + margin: 7px 5px 3px 5px; } -} \ No newline at end of file +} diff --git a/assets/styles/targets.scss b/assets/styles/targets.scss index a61fc2f..9c5d4b3 100644 --- a/assets/styles/targets.scss +++ b/assets/styles/targets.scss @@ -9,9 +9,20 @@ } } .content { - padding: 14px 14px 42px 14px; + padding: 14px 0 42px 0; + position: relative; + .error-box { + height: 30px; + line-height: 30px; + background: $red; + color: white; + padding: 0 14px; + margin: -14px 0 8px 0; + } header { + padding: 0 14px; + h1 { text-shadow: 1px 1px 2px $black-3; } @@ -26,9 +37,15 @@ } } .list { - margin: 14px 0; + margin: 14px; padding: 0; list-style: none; overflow: hidden; } + &.working { + & > .progress { + top: 0; + height: 4px; + } + } }