From 99b2b8633db4fa3fa21d43f3e6a27694b00908e4 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 16 Jun 2016 12:20:32 +0800 Subject: [web] settings store --- web/src/js/components/ProxyApp.jsx | 33 ++-------------- web/src/js/connection.js | 6 ++- web/src/js/ducks/index.js | 2 + web/src/js/ducks/settings.js | 81 ++++++++++++++++++++++++++++++++++++++ web/src/js/store/store.js | 2 +- 5 files changed, 92 insertions(+), 32 deletions(-) create mode 100644 web/src/js/ducks/settings.js (limited to 'web/src') diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index 81272268..d7f640a3 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -7,7 +7,6 @@ import { Splitter } from "./common.js" import Header from "./Header" import EventLog from "./EventLog" import Footer from "./Footer" -import { SettingsStore } from "../store/store.js" import { Key } from "../utils.js" class ProxyAppMain extends Component { @@ -24,17 +23,9 @@ class ProxyAppMain extends Component { constructor(props, context) { super(props, context) - this.settingsStore = new SettingsStore() - - // Default Settings before fetch - _.extend(this.settingsStore.dict, {}) - - this.state = { settings: this.settingsStore.dict } - this.focus = this.focus.bind(this) this.onKeyDown = this.onKeyDown.bind(this) this.updateLocation = this.updateLocation.bind(this) - this.onSettingsChange = this.onSettingsChange.bind(this) } /** @@ -61,29 +52,11 @@ class ProxyAppMain extends Component { } /** - * @todo remove settings store * @todo connect websocket here * @todo listen to window's key events */ componentDidMount() { this.focus() - this.settingsStore.addListener("recalculate", this.onSettingsChange) - } - - /** - * @todo remove settings store - * @todo disconnect websocket here - * @todo stop listening to window's key events - */ - componentWillUnmount() { - this.settingsStore.removeListener("recalculate", this.onSettingsChange) - } - - /** - * @todo move to actions - */ - onSettingsChange() { - this.setState({ settings: this.settingsStore.dict }) } /** @@ -143,8 +116,7 @@ class ProxyAppMain extends Component { } render() { - const { showEventLog, location, children } = this.props - const { settings } = this.state + const { showEventLog, location, children, settings } = this.props const query = this.getQuery() return (
@@ -165,6 +137,7 @@ class ProxyAppMain extends Component { export default connect( state => ({ - showEventLog: state.eventLog.visible + showEventLog: state.eventLog.visible, + settings: state.settings.settings, }) )(ProxyAppMain) diff --git a/web/src/js/connection.js b/web/src/js/connection.js index 5961909e..a2582288 100644 --- a/web/src/js/connection.js +++ b/web/src/js/connection.js @@ -3,6 +3,7 @@ import {AppDispatcher} from "./dispatcher.js"; import * as webSocketActions from "./ducks/websocket" import * as eventLogActions from "./ducks/eventLog" import * as flowActions from "./ducks/flows" +import * as settingsActions from './ducks/settings' export default function Connection(url, dispatch) { if (url[0] === "/") { @@ -12,6 +13,7 @@ export default function Connection(url, dispatch) { var ws = new WebSocket(url); ws.onopen = function () { dispatch(webSocketActions.connected()) + dispatch(settingsActions.fetch()) dispatch(flowActions.fetchFlows()) // workaround to make sure that our state is already available. .then(() => { @@ -28,6 +30,8 @@ export default function Connection(url, dispatch) { return dispatch(eventLogActions.updateLogEntries(message)) case flowActions.UPDATE_FLOWS: return dispatch(flowActions.updateFlows(message)) + case settingsActions.WS_MSG_TYPE: + return dispatch(settingsActions.handleWsMsg(message)) default: console.warn("unknown message", message) } @@ -42,4 +46,4 @@ export default function Connection(url, dispatch) { dispatch(webSocketActions.disconnected()); }; return ws; -} \ No newline at end of file +} diff --git a/web/src/js/ducks/index.js b/web/src/js/ducks/index.js index fee4d792..ffde1a64 100644 --- a/web/src/js/ducks/index.js +++ b/web/src/js/ducks/index.js @@ -2,12 +2,14 @@ import {combineReducers} from 'redux' import eventLog from './eventLog' import websocket from './websocket' import flows from './flows' +import settings from './settings' import ui from './ui' const rootReducer = combineReducers({ eventLog, websocket, flows, + settings, ui }) diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js new file mode 100644 index 00000000..8513c2f1 --- /dev/null +++ b/web/src/js/ducks/settings.js @@ -0,0 +1,81 @@ +import { StoreCmds } from '../actions' + +export const WS_MSG_TYPE = 'settings' +export const WS_MSG_CMD_RESET = 'reset' +export const WS_MSG_CMD_UPDATE = 'update' + +export const BEGIN_FETCH = 'SETTINGS_BEGIN_FETCH' +export const FETCH_SETTINGS = 'SETTINGS_FETCH_SETTINGS' +export const FETCH_ERROR = 'SETTINGS_FETCH_ERROR' +export const RECV_WS_MSG = 'SETTINGS_RECV_WS_MSG' + +const defaultState = { settings: {}, pendings: null, req: null } + +function reduceData(data, action) { + switch (action.cmd) { + + case WS_MSG_CMD_RESET: + return action.data || {} + + case WS_MSG_CMD_UPDATE: + return _.merge({}, data.settings, action.data) + + default: + return data + } +} + +export default function reduce(state = defaultState, action) { + switch (action.type) { + + case BEGIN_FETCH: + return { ...state, pendings: [], req: action.req } + + case FETCH_SETTINGS: + const pendings = state.pendings || [] + return { ...state, pendings: null, settings: pendings.reduce(reduceData, data) } + + case RECV_WS_MSG: + if (state.pendings) { + return { ...state, pendings: state.pendings.concat(action) } + } + return { ...state, settings: reduceData(state.settings, action) } + + default: + return state + } +} + +export function fetch() { + return dispatch => { + const req = $.getJSON('/' + this.type) + .done(msg => dispatch(reset(msg.data))) + .fail(error => dispatch(handleFetchError(error))); + + dispatch({ type: BEGIN_FETCH, req }) + + return req + } +} + +export function handleWsMsg(msg) { + return (dispatch, getState) => { + if (msg.cmd === STORE_CMDS_RESET) { + const req = getState().settings.req + if (req) { + req.abort() + } + return dispatch(reset(msg.data)) + } + dispatch({ type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data }) + } +} + +export function reset(data) { + return { type: FETCH_SETTINGS, data } +} + +export function handleFetchError(error) { + console.error(error) + return { type: FETCH_ERROR, error } +} diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js index f3e2074f..2744a6fa 100644 --- a/web/src/js/store/store.js +++ b/web/src/js/store/store.js @@ -93,4 +93,4 @@ _.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype) export function SettingsStore() { return new LiveDictStore(ActionTypes.SETTINGS_STORE); -} \ No newline at end of file +} -- cgit v1.2.3 From b88937f1e039e306f95a760ea181fcdcc6fec1fa Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 16 Jun 2016 12:25:17 +0800 Subject: [web] eliminate SettingsStore --- web/src/js/store/store.js | 5 ----- 1 file changed, 5 deletions(-) (limited to 'web/src') diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js index 2744a6fa..df3a23ab 100644 --- a/web/src/js/store/store.js +++ b/web/src/js/store/store.js @@ -89,8 +89,3 @@ function LiveDictStore(type) { LiveStoreMixin.call(this, type); } _.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype); - - -export function SettingsStore() { - return new LiveDictStore(ActionTypes.SETTINGS_STORE); -} -- cgit v1.2.3 From 7fb0836bfedefd851403ba440e88bc04548cf7b0 Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 16 Jun 2016 16:46:13 +0800 Subject: [web] remove store --- web/src/js/ducks/settings.js | 14 +++---- web/src/js/store/store.js | 91 -------------------------------------------- web/src/js/store/view.js | 0 3 files changed, 7 insertions(+), 98 deletions(-) delete mode 100644 web/src/js/store/store.js delete mode 100644 web/src/js/store/view.js (limited to 'web/src') diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 8513c2f1..05499da5 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -60,14 +60,14 @@ export function fetch() { export function handleWsMsg(msg) { return (dispatch, getState) => { - if (msg.cmd === STORE_CMDS_RESET) { - const req = getState().settings.req - if (req) { - req.abort() - } - return dispatch(reset(msg.data)) + if (msg.cmd !== STORE_CMDS_RESET) { + return dispatch({ type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data }) + } + const req = getState().settings.req + if (req) { + req.abort() } - dispatch({ type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data }) + dispatch(reset(msg.data)) } } diff --git a/web/src/js/store/store.js b/web/src/js/store/store.js deleted file mode 100644 index df3a23ab..00000000 --- a/web/src/js/store/store.js +++ /dev/null @@ -1,91 +0,0 @@ - -import _ from "lodash"; -import $ from "jquery"; -import {EventEmitter} from 'events'; -import {ActionTypes, StoreCmds} from "../actions.js"; -import {AppDispatcher} from "../dispatcher.js"; - - -function DictStore() { - EventEmitter.call(this); - this.reset(); -} -_.extend(DictStore.prototype, EventEmitter.prototype, { - update: function (dict) { - _.merge(this.dict, dict); - this.emit("recalculate"); - }, - reset: function (dict) { - this.dict = dict || {}; - this.emit("recalculate"); - } -}); - -function LiveStoreMixin(type) { - this.type = type; - - this._updates_before_fetch = undefined; - this._fetchxhr = false; - - this.handle = this.handle.bind(this); - AppDispatcher.register(this.handle); - - // Avoid double-fetch on startup. - if (!(window.ws && window.ws.readyState === WebSocket.CONNECTING)) { - this.fetch(); - } -} -_.extend(LiveStoreMixin.prototype, { - handle: function (event) { - if (event.type === ActionTypes.CONNECTION_OPEN) { - return this.fetch(); - } - if (event.type === this.type) { - if (event.cmd === StoreCmds.RESET) { - this.fetch(event.data); - } else if (this._updates_before_fetch) { - console.log("defer update", event); - this._updates_before_fetch.push(event); - } else { - this[event.cmd](event.data); - } - } - }, - close: function () { - AppDispatcher.unregister(this.handle); - }, - fetch: function (data) { - console.log("fetch " + this.type); - if (this._fetchxhr) { - this._fetchxhr.abort(); - } - this._updates_before_fetch = []; // (JS: empty array is true) - if (data) { - this.handle_fetch(data); - } else { - this._fetchxhr = $.getJSON("/" + this.type) - .done(function (message) { - this.handle_fetch(message.data); - }.bind(this)) - .fail(function () { - console.error("Could not fetch " + this.type) - }.bind(this)); - } - }, - handle_fetch: function (data) { - this._fetchxhr = false; - console.log(this.type + " fetched.", this._updates_before_fetch); - this.reset(data); - var updates = this._updates_before_fetch; - this._updates_before_fetch = false; - for (var i = 0; i < updates.length; i++) { - this.handle(updates[i]); - } - }, -}); - -function LiveDictStore(type) { - DictStore.call(this); - LiveStoreMixin.call(this, type); -} -_.extend(LiveDictStore.prototype, DictStore.prototype, LiveStoreMixin.prototype); diff --git a/web/src/js/store/view.js b/web/src/js/store/view.js deleted file mode 100644 index e69de29b..00000000 -- cgit v1.2.3 From cedac98b700efc6d1a38378e673626f07bff916d Mon Sep 17 00:00:00 2001 From: Jason Date: Thu, 16 Jun 2016 17:21:57 +0800 Subject: [web] promot reduce --- web/src/js/ducks/settings.js | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'web/src') diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 05499da5..41e99d29 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -1,4 +1,5 @@ import { StoreCmds } from '../actions' +import { addLogEntry } from './eventLog' export const WS_MSG_TYPE = 'settings' export const WS_MSG_CMD_RESET = 'reset' @@ -11,20 +12,6 @@ export const RECV_WS_MSG = 'SETTINGS_RECV_WS_MSG' const defaultState = { settings: {}, pendings: null, req: null } -function reduceData(data, action) { - switch (action.cmd) { - - case WS_MSG_CMD_RESET: - return action.data || {} - - case WS_MSG_CMD_UPDATE: - return _.merge({}, data.settings, action.data) - - default: - return data - } -} - export default function reduce(state = defaultState, action) { switch (action.type) { @@ -46,6 +33,20 @@ export default function reduce(state = defaultState, action) { } } +function reduceData(data, action) { + switch (action.cmd) { + + case WS_MSG_CMD_RESET: + return action.data || {} + + case WS_MSG_CMD_UPDATE: + return _.merge({}, data.settings, action.data) + + default: + return data + } +} + export function fetch() { return dispatch => { const req = $.getJSON('/' + this.type) @@ -76,6 +77,8 @@ export function reset(data) { } export function handleFetchError(error) { - console.error(error) - return { type: FETCH_ERROR, error } + return (dispatch, getState) => { + dispatch(addLogEntry(error.stack || error.message || error)) + dispatch({ type: FETCH_ERROR, error }) + } } -- cgit v1.2.3 From 6ad2f13341208b8460eae0dd0105c3109e773bae Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 17 Jun 2016 06:01:29 +0800 Subject: [web] fix settings ducks --- web/src/js/components/ProxyApp.jsx | 10 +++++++++- web/src/js/ducks/settings.js | 24 ++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) (limited to 'web/src') diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index d7f640a3..1d27614f 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -3,6 +3,7 @@ import ReactDOM from "react-dom" import _ from "lodash" import { connect } from 'react-redux' +import { fetch as fetchSettings } from '../ducks/settings' import { Splitter } from "./common.js" import Header from "./Header" import EventLog from "./EventLog" @@ -51,6 +52,10 @@ class ProxyAppMain extends Component { return _.clone(this.props.location.query) } + componentWillMount() { + this.props.fetchSettings(); + } + /** * @todo connect websocket here * @todo listen to window's key events @@ -139,5 +144,8 @@ export default connect( state => ({ showEventLog: state.eventLog.visible, settings: state.settings.settings, - }) + }), + { + fetchSettings, + } )(ProxyAppMain) diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 41e99d29..37ff04de 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -6,7 +6,8 @@ export const WS_MSG_CMD_RESET = 'reset' export const WS_MSG_CMD_UPDATE = 'update' export const BEGIN_FETCH = 'SETTINGS_BEGIN_FETCH' -export const FETCH_SETTINGS = 'SETTINGS_FETCH_SETTINGS' +export const FETCHED = 'SETTINGS_FETCHED' +export const RESET = 'SETTINGS_RESET' export const FETCH_ERROR = 'SETTINGS_FETCH_ERROR' export const RECV_WS_MSG = 'SETTINGS_RECV_WS_MSG' @@ -18,9 +19,12 @@ export default function reduce(state = defaultState, action) { case BEGIN_FETCH: return { ...state, pendings: [], req: action.req } - case FETCH_SETTINGS: + case FETCHED: const pendings = state.pendings || [] - return { ...state, pendings: null, settings: pendings.reduce(reduceData, data) } + return { ...state, pendings: null, settings: pendings.reduce(reduceData, action.data) } + + case RESET: + return { ...state, pendings: null, settings: action.data || {} } case RECV_WS_MSG: if (state.pendings) { @@ -40,7 +44,7 @@ function reduceData(data, action) { return action.data || {} case WS_MSG_CMD_UPDATE: - return _.merge({}, data.settings, action.data) + return _.merge({}, data, action.data) default: return data @@ -49,8 +53,8 @@ function reduceData(data, action) { export function fetch() { return dispatch => { - const req = $.getJSON('/' + this.type) - .done(msg => dispatch(reset(msg.data))) + const req = $.getJSON('/settings') + .done(msg => dispatch(handleFetchResponse(msg.data))) .fail(error => dispatch(handleFetchError(error))); dispatch({ type: BEGIN_FETCH, req }) @@ -61,7 +65,7 @@ export function fetch() { export function handleWsMsg(msg) { return (dispatch, getState) => { - if (msg.cmd !== STORE_CMDS_RESET) { + if (msg.cmd !== StoreCmds.RESET) { return dispatch({ type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data }) } const req = getState().settings.req @@ -72,8 +76,12 @@ export function handleWsMsg(msg) { } } +export function handleFetchResponse(data) { + return { type: FETCHED, data } +} + export function reset(data) { - return { type: FETCH_SETTINGS, data } + return { type: RESET, data } } export function handleFetchError(error) { -- cgit v1.2.3 From 965b27b52942cc6bf082355a1540bc0f960f1043 Mon Sep 17 00:00:00 2001 From: Jason Date: Fri, 17 Jun 2016 22:02:34 +0800 Subject: [web] simplify settings --- web/src/js/ducks/settings.js | 44 ++++++++------------------------------------ 1 file changed, 8 insertions(+), 36 deletions(-) (limited to 'web/src') diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 37ff04de..6de1c2af 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -1,31 +1,24 @@ -import { StoreCmds } from '../actions' import { addLogEntry } from './eventLog' export const WS_MSG_TYPE = 'settings' -export const WS_MSG_CMD_RESET = 'reset' export const WS_MSG_CMD_UPDATE = 'update' export const BEGIN_FETCH = 'SETTINGS_BEGIN_FETCH' export const FETCHED = 'SETTINGS_FETCHED' -export const RESET = 'SETTINGS_RESET' -export const FETCH_ERROR = 'SETTINGS_FETCH_ERROR' export const RECV_WS_MSG = 'SETTINGS_RECV_WS_MSG' -const defaultState = { settings: {}, pendings: null, req: null } +const defaultState = { settings: {}, pendings: null } export default function reduce(state = defaultState, action) { switch (action.type) { case BEGIN_FETCH: - return { ...state, pendings: [], req: action.req } + return { ...state, pendings: [] } case FETCHED: const pendings = state.pendings || [] return { ...state, pendings: null, settings: pendings.reduce(reduceData, action.data) } - case RESET: - return { ...state, pendings: null, settings: action.data || {} } - case RECV_WS_MSG: if (state.pendings) { return { ...state, pendings: state.pendings.concat(action) } @@ -40,11 +33,8 @@ export default function reduce(state = defaultState, action) { function reduceData(data, action) { switch (action.cmd) { - case WS_MSG_CMD_RESET: - return action.data || {} - case WS_MSG_CMD_UPDATE: - return _.merge({}, data, action.data) + return { ...data, ...action.data } default: return data @@ -53,40 +43,22 @@ function reduceData(data, action) { export function fetch() { return dispatch => { - const req = $.getJSON('/settings') + dispatch({ type: BEGIN_FETCH }) + return $.getJSON('/settings') .done(msg => dispatch(handleFetchResponse(msg.data))) .fail(error => dispatch(handleFetchError(error))); - - dispatch({ type: BEGIN_FETCH, req }) - - return req } } export function handleWsMsg(msg) { - return (dispatch, getState) => { - if (msg.cmd !== StoreCmds.RESET) { - return dispatch({ type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data }) - } - const req = getState().settings.req - if (req) { - req.abort() - } - dispatch(reset(msg.data)) - } + return { type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data } } export function handleFetchResponse(data) { return { type: FETCHED, data } } -export function reset(data) { - return { type: RESET, data } -} - export function handleFetchError(error) { - return (dispatch, getState) => { - dispatch(addLogEntry(error.stack || error.message || error)) - dispatch({ type: FETCH_ERROR, error }) - } + // @todo let eventLog subscribe to SettingsActions.FETCH_ERROR + return addLogEntry(error.stack || error.message || error) } -- cgit v1.2.3 From ce53799c623a8ac74631f6fc4ab8fb134bff1cc8 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 17 Jun 2016 21:03:19 -0700 Subject: simplify settings reducer --- web/src/js/components/ProxyApp.jsx | 11 +---- web/src/js/connection.js | 6 +-- web/src/js/ducks/settings.js | 96 +++++++++++++++++++++----------------- 3 files changed, 56 insertions(+), 57 deletions(-) (limited to 'web/src') diff --git a/web/src/js/components/ProxyApp.jsx b/web/src/js/components/ProxyApp.jsx index 8129b0f0..39cadff5 100644 --- a/web/src/js/components/ProxyApp.jsx +++ b/web/src/js/components/ProxyApp.jsx @@ -3,7 +3,6 @@ import ReactDOM from 'react-dom' import _ from 'lodash' import { connect } from 'react-redux' -import { fetch as fetchSettings } from '../ducks/settings' import Header from './Header' import EventLog from './EventLog' import Footer from './Footer' @@ -50,12 +49,7 @@ class ProxyAppMain extends Component { return _.clone(this.props.location.query) } - componentWillMount() { - this.props.fetchSettings(); - } - /** - * @todo connect websocket here * @todo listen to window's key events */ componentDidMount() { @@ -139,8 +133,5 @@ export default connect( state => ({ showEventLog: state.eventLog.visible, settings: state.settings.settings, - }), - { - fetchSettings, - } + }) )(ProxyAppMain) diff --git a/web/src/js/connection.js b/web/src/js/connection.js index a2582288..786a6394 100644 --- a/web/src/js/connection.js +++ b/web/src/js/connection.js @@ -13,7 +13,7 @@ export default function Connection(url, dispatch) { var ws = new WebSocket(url); ws.onopen = function () { dispatch(webSocketActions.connected()) - dispatch(settingsActions.fetch()) + dispatch(settingsActions.fetchSettings()) dispatch(flowActions.fetchFlows()) // workaround to make sure that our state is already available. .then(() => { @@ -30,8 +30,8 @@ export default function Connection(url, dispatch) { return dispatch(eventLogActions.updateLogEntries(message)) case flowActions.UPDATE_FLOWS: return dispatch(flowActions.updateFlows(message)) - case settingsActions.WS_MSG_TYPE: - return dispatch(settingsActions.handleWsMsg(message)) + case settingsActions.UPDATE_SETTINGS: + return dispatch(settingsActions.updateSettings(message)) default: console.warn("unknown message", message) } diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 6de1c2af..479d1300 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -1,64 +1,72 @@ -import { addLogEntry } from './eventLog' +import {fetchApi} from "../utils"; -export const WS_MSG_TYPE = 'settings' -export const WS_MSG_CMD_UPDATE = 'update' +export const REQUEST_SETTINGS = "REQUEST_SETTINGS" +export const RECEIVE_SETTINGS = "RECEIVE_SETTINGS" +export const UPDATE_SETTINGS = "UPDATE_SETTINGS" -export const BEGIN_FETCH = 'SETTINGS_BEGIN_FETCH' -export const FETCHED = 'SETTINGS_FETCHED' -export const RECV_WS_MSG = 'SETTINGS_RECV_WS_MSG' - -const defaultState = { settings: {}, pendings: null } +const defaultState = { + settings: {}, + isFetching: false, + actionsDuringFetch: [], +} -export default function reduce(state = defaultState, action) { +export default function reducer(state = defaultState, action) { switch (action.type) { - case BEGIN_FETCH: - return { ...state, pendings: [] } + case REQUEST_SETTINGS: + return { + ...state, + isFetching: true + } - case FETCHED: - const pendings = state.pendings || [] - return { ...state, pendings: null, settings: pendings.reduce(reduceData, action.data) } + case RECEIVE_SETTINGS: + let s = { + settings: action.settings, + isFetching: false, + actionsDuringFetch: [], + } + for (action of state.actionsDuringFetch) { + s = reducer(s, action) + } + return s - case RECV_WS_MSG: - if (state.pendings) { - return { ...state, pendings: state.pendings.concat(action) } + case UPDATE_SETTINGS: + if (state.isFetching) { + return { + ...state, + actionsDuringFetch: [...state.actionsDuringFetch, action] + } + } + return { + ...state, + settings: {...state.settings, ...action.settings} } - return { ...state, settings: reduceData(state.settings, action) } default: return state } } -function reduceData(data, action) { - switch (action.cmd) { - - case WS_MSG_CMD_UPDATE: - return { ...data, ...action.data } - - default: - return data +export function updateSettings(event) { + /* This action creator takes all WebSocket events */ + if (event.cmd === "update") { + return { + type: UPDATE_SETTINGS, + settings: event.data + } } + console.error("unknown settings update", event) } -export function fetch() { +export function fetchSettings() { return dispatch => { - dispatch({ type: BEGIN_FETCH }) - return $.getJSON('/settings') - .done(msg => dispatch(handleFetchResponse(msg.data))) - .fail(error => dispatch(handleFetchError(error))); - } -} - -export function handleWsMsg(msg) { - return { type: RECV_WS_MSG, cmd: msg.cmd, data: msg.data } -} - -export function handleFetchResponse(data) { - return { type: FETCHED, data } -} + dispatch({type: REQUEST_SETTINGS}) -export function handleFetchError(error) { - // @todo let eventLog subscribe to SettingsActions.FETCH_ERROR - return addLogEntry(error.stack || error.message || error) + return fetchApi("/settings") + .then(response => response.json()) + .then(json => + dispatch({type: RECEIVE_SETTINGS, settings: json.data}) + ) + // TODO: Error handling + } } -- cgit v1.2.3 From 6a41ea91714711f2edc07af0329621de3191aa22 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 17 Jun 2016 21:05:30 -0700 Subject: add fetchApi.put shortcut --- web/src/js/utils.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'web/src') diff --git a/web/src/js/utils.js b/web/src/js/utils.js index 2e5c3005..2e25016e 100644 --- a/web/src/js/utils.js +++ b/web/src/js/utils.js @@ -109,7 +109,19 @@ export function fetchApi(url, options) { url += "&" + xsrf; } return fetch(url, { - ...options, - credentials: 'same-origin' + credentials: 'same-origin', + ...options }); -} \ No newline at end of file +} + +fetchApi.put = (url, json, options) => fetchApi( + url, + { + method: "PUT", + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(json), + ...options + } +) -- cgit v1.2.3 From f203936fbf51b04f424666f9d2dd63bce8c84404 Mon Sep 17 00:00:00 2001 From: Maximilian Hils Date: Fri, 17 Jun 2016 21:06:17 -0700 Subject: add setInterceptPattern action creator --- web/src/js/components/Header/MainMenu.jsx | 11 ++++++++--- web/src/js/ducks/settings.js | 5 +++++ 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'web/src') diff --git a/web/src/js/components/Header/MainMenu.jsx b/web/src/js/components/Header/MainMenu.jsx index 86bf961a..7b0b542c 100644 --- a/web/src/js/components/Header/MainMenu.jsx +++ b/web/src/js/components/Header/MainMenu.jsx @@ -1,9 +1,10 @@ import React, { Component, PropTypes } from 'react' -import { SettingsActions } from "../../actions.js" import FilterInput from './FilterInput' import { Query } from '../../actions.js' +import {setInterceptPattern} from "../../ducks/settings" +import { connect } from 'react-redux' -export default class MainMenu extends Component { +class MainMenu extends Component { static title = 'Start' static route = 'flows' @@ -28,7 +29,7 @@ export default class MainMenu extends Component { } onInterceptChange(val) { - SettingsActions.update({ intercept: val }) + this.props.setInterceptPattern(val); } render() { @@ -71,3 +72,7 @@ export default class MainMenu extends Component { ) } } + +export default connect(undefined, { + setInterceptPattern +})(MainMenu); diff --git a/web/src/js/ducks/settings.js b/web/src/js/ducks/settings.js index 479d1300..73c62120 100644 --- a/web/src/js/ducks/settings.js +++ b/web/src/js/ducks/settings.js @@ -70,3 +70,8 @@ export function fetchSettings() { // TODO: Error handling } } + +export function setInterceptPattern(intercept) { + return dispatch => + fetchApi.put("/settings", {intercept}) +} -- cgit v1.2.3