Initial plumbing for moving to Redux

This commit is contained in:
Aaron Lindsay 2016-10-03 19:49:15 -04:00
parent 449b4ee760
commit 4f2f15783a
9 changed files with 304 additions and 2 deletions

2
README
View File

@ -10,4 +10,4 @@ Install browserify globally:
$ sudo npm install -g browserify
Next, install browserify, babel, react, react-bootstrap, react-widgets, globalize, and big.js in our directory using npm:
$ npm install browserify react react-dom react-addons-update react-bootstrap react-widgets babelify babel-preset-react globalize cldr-data big.js
$ npm install browserify react react-dom react-addons-update react-bootstrap react-widgets redux react-redux redux-thunk babelify babel-preset-react globalize cldr-data big.js keymirror

View File

@ -0,0 +1,181 @@
var AccountConstants = require('../constants/AccountConstants');
var ErrorActions = require('ErrorActions');
var models = require('../models.js');
var Account = models.Account;
var Error = models.Error;
function fetchAccounts() {
return {
type: AccountConstants.FETCH_ACCOUNTS
}
}
function accountsFetched(accounts) {
return {
type: AccountConstants.ACCOUNTS_FETCHED,
accounts: accounts
}
}
function createAccount() {
return {
type: AccountConstants.CREATE_ACCOUNT
}
}
function accountCreated(account) {
return {
type: AccountConstants.ACCOUNT_CREATED,
account: account
}
}
function updateAccount() {
return {
type: AccountConstants.UPDATE_ACCOUNT
}
}
function accountUpdated(account) {
return {
type: AccountConstants.ACCOUNT_UPDATED,
account: account
}
}
function removeAccount() {
return {
type: AccountConstants.REMOVE_ACCOUNT
}
}
function accountRemoved(accountId) {
return {
type: AccountConstants.ACCOUNT_REMOVED,
accountId: accountId
}
}
function accountSelected(accountId) {
return {
type: AccountConstants.ACCOUNT_SELECTED,
accountId: accountId
}
}
function fetchAll() {
return function (dispatch) {
dispatch(fetchAccounts());
$.ajax({
type: "GET",
dataType: "json",
url: "account/",
success: function(data, status, jqXHR) {
var e = new Error();
var accounts = [];
e.fromJSON(data);
if (e.isError()) {
ErrorActions.serverError(e);
} else {
dispatch(accountsFetched(data.accounts.map(function(json) {
var a = new Account();
a.fromJSON(json);
return a;
})));
}
},
error: function(jqXHR, status, error) {
ErrorActions.ajaxError(e);
}
});
};
}
function create(account) {
return function (dispatch) {
dispatch(createAccount());
$.ajax({
type: "POST",
dataType: "json",
url: "account/",
data: {account: account.toJSON()},
success: function(data, status, jqXHR) {
var e = new Error();
e.fromJSON(data);
if (e.isError()) {
ErrorActions.serverError(e);
} else {
var a = new Account();
a.fromJSON(data);
dispatch(accountCreated(a));
}
},
error: function(jqXHR, status, error) {
ErrorActions.ajaxError(e);
}
});
};
}
function update(account) {
return function (dispatch) {
dispatch(updateAccount());
$.ajax({
type: "PUT",
dataType: "json",
url: "account/"+account.AccountId+"/",
data: {account: account.toJSON()},
success: function(data, status, jqXHR) {
var e = new Error();
e.fromJSON(data);
if (e.isError()) {
ErrorActions.serverError(e);
} else {
var a = new Account();
a.fromJSON(data);
dispatch(accountUpdated(a));
}
},
error: function(jqXHR, status, error) {
ErrorActions.ajaxError(e);
}
});
};
}
function remove(account) {
return function(dispatch) {
dispatch(removeAccount());
$.ajax({
type: "DELETE",
dataType: "json",
url: "account/"+account.AccountId+"/",
success: function(data, status, jqXHR) {
var e = new Error();
e.fromJSON(data);
if (e.isError()) {
ErrorActions.serverError(e);
} else {
dispatch(accountRemoved(account.AccountId));
}
},
error: function(jqXHR, status, error) {
ErrorActions.ajaxError(e);
}
});
};
}
module.exports = {
fetchAll: fetchAll,
create: create,
update: update,
remove: remove,
select: accountSelected
};

View File

@ -0,0 +1,27 @@
var ErrorConstants = require('../constants/ErrorConstants');
var models = require('../models.js');
var Error = models.Error;
function serverError(error) {
return {
type: ErrorConstants.ERROR_SERVER,
error: error
};
}
function ajaxError(error) {
var e = new Error();
e.ErrorId = 5;
e.ErrorString = "Request Failed: " + status + error;
return {
type: ErrorConstants.ERROR_AJAX,
error: e
};
}
module.exports = {
serverError: serverError,
ajaxError: ajaxError
};

View File

@ -0,0 +1,13 @@
var keyMirror = require('keymirror');
module.exports = keyMirror({
FETCH_ACCOUNTS: null,
ACCOUNTS_FETCHED: null,
CREATE_ACCOUNT: null,
ACCOUNT_CREATED: null,
UPDATE_ACCOUNT: null,
ACCOUNT_UPDATED: null,
REMOVE_ACCOUNT: null,
ACCOUNT_REMOVED: null,
ACCOUNT_SELECTED: null
});

View File

@ -0,0 +1,8 @@
var keyMirror = require('keymirror');
module.exports = keyMirror({
ERROR_AJAX: null,
ERROR_SERVER: null,
ERROR_CLIENT: null,
ERROR_USER: null,
});

View File

@ -1,10 +1,15 @@
var React = require('react');
var ReactDOM = require('react-dom');
var Provider = require('react-redux').Provider;
var Redux = require('redux');
var ReduxThunk = require('redux-thunk').default;
var Globalize = require('globalize');
var globalizeLocalizer = require('react-widgets/lib/localizers/globalize');
var MoneyGoApp = require('./MoneyGoApp.js');
var MoneyGoReducer = require('./reducers/MoneyGoReducer');
// Setup globalization for react-widgets
//Globalize.load(require("cldr-data").entireSupplemental());
@ -19,5 +24,17 @@ Globalize.locale('en');
globalizeLocalizer(Globalize);
$(document).ready(function() {
ReactDOM.render(<MoneyGoApp />, document.getElementById("content"));
var store = Redux.createStore(
MoneyGoReducer,
Redux.applyMiddleware(
ReduxThunk
)
);
ReactDOM.render(
<Provider store={store}>
<MoneyGoApp />
</Provider>,
document.getElementById("content")
);
});

View File

@ -0,0 +1,27 @@
var assign = require('object-assign');
var AccountConstants = require('../constants/AccountConstants');
module.exports = function(state = {}, action) {
switch (action.type) {
case AccountConstants.ACCOUNTS_FETCHED:
var accounts = {};
for (var i = 0; i < action.accounts.length; i++) {
var account = action.accounts[i];
accounts[account.AccountId] = account;
}
return accounts;
case AccountConstants.ACCOUNT_CREATED:
case AccountConstants.ACCOUNT_UPDATED:
var account = action.account;
return assign({}, state, {
[account.AccountId]: account
});
case AccountConstants.ACCOUNT_REMOVED:
var newstate = assign({}, state);
delete newstate[action.accountId];
return newstate;
default:
return state;
}
};

View File

@ -0,0 +1,9 @@
var Redux = require('redux');
var AccountReducer = require('./AccountReducer');
var SelectedAccountReducer = require('./SelectedAccountReducer');
module.exports = Redux.combineReducers({
accounts: AccountReducer,
selectedAccount: SelectedAccountReducer
});

View File

@ -0,0 +1,20 @@
var AccountConstants = require('../constants/AccountConstants');
module.exports = function(state = -1, action) {
switch (action.type) {
case AccountConstants.ACCOUNTS_FETCHED:
for (var i = 0; i < action.accounts.length; i++) {
if (action.accounts[i].AccountId == state)
return state;
}
return -1;
case AccountConstants.ACCOUNT_REMOVED:
if (action.accountId == state)
return -1;
return state;
case AccountConstants.ACCOUNT_SELECTED:
return action.accountId;
default:
return state;
}
};