diff --git a/CHANGELOG.md b/CHANGELOG.md index a67f11d..db7aff7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +# 0.1.5 +Change selector payload type of data, now it's *Immutable JSON or unndefined* please see [test-source](https://github.com/edtoken/redux-tide/blob/master/test/selector.spec.js#L48) +Add query builder result to action store and selector response `args` +Implement `action.remove` +Implement `action.recall` +Improve documentation +Improve examples, add new example +Add code sandbox examples +Add new badges + +# 0.1.4 + # 0.1.3 Fix critical bug in method `Action.empty` small refactoring action.js, selector.js files diff --git a/README.md b/README.md index 8de1e2e..0a72e9d 100644 --- a/README.md +++ b/README.md @@ -22,14 +22,16 @@ ActionCreator + ActionSelector, reducers are created automatically [coverage-report](https://edtoken.github.io/redux-tide/coverage/lcov-report/index.html) -[](https://gitter.im/practice-feature/redux-tide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[](https://gitter.im/practice-feature/redux-tide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [](https://badge.fury.io/js/redux-tide) [](https://travis-ci.org/edtoken/redux-tide) [](https://codeclimate.com/github/edtoken/redux-tide/maintainability) [](https://www.npmjs.com/package/redux-tide) [](https://coveralls.io/github/edtoken/redux-tide?branch=master) -[](https://inch-ci.org/github/edtoken/redux-tide) +[](https://inch-ci.org/github/edtoken/redux-tide) +[](https://david-dm.org/edtoken/redux-tide) +[](https://david-dm.org/edtoken/redux-tide?type=dev) [](http://hits.dwyl.com/edtoken/redux-tide) [](https://nodei.co/npm/redux-tide/) @@ -96,7 +98,7 @@ npm install redux-thunk --save ------ ### Discussion You can connect to [Gitter chat room](https://gitter.im/practice-feature/redux-tide) -[](https://gitter.im/practice-feature/redux-tide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[](https://gitter.im/practice-feature/redux-tide?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) ### Usage 1. You might install library @@ -227,12 +229,22 @@ export const createNewPost = createAction( ] ) +export const getPostById = createAction( + postsSchema, + get, + (postId) => { + return (dispatch, getState)=>{ + // return Promise (axios call or other) + } + } +) + // basic redux action can be use export const openEditPost = (postId) => { return { type:OPEN_EDIT, postId - } + } } ``` @@ -324,6 +336,7 @@ import {getActionData} from 'redux-tide'; ``` {String} actionId - your action id {*} sourceResult - your source response from server (not mapped response) +{*} args - your args from query builder action method {String} status - pending|success|error {Number} time - timestamp of action {Boolean} hasError - has error or not diff --git a/lib/action.js b/lib/action.js index 726f6b9..06f0a33 100644 --- a/lib/action.js +++ b/lib/action.js @@ -69,9 +69,10 @@ var makeActionHandler = function makeActionHandler(Action, actionId, parentActio * * @param {String} error - action error text * @param {Object|Array} payloadSource - response from action result + * @param {Object|Array} args - arguments from queryBuilder * @returns {Object} - action dispatch body */ - return function (error, payloadSource, sourceResult) { + return function (error, payloadSource, sourceResult, args) { if (status === 'success' && payloadSource === undefined) { error = 'Empty payload'; status = 'error'; @@ -117,10 +118,11 @@ var makeActionHandler = function makeActionHandler(Action, actionId, parentActio * payloadSource: Object|Array * }} */ - return Object.freeze({ + return { time: new Date().getTime(), type: '' + actionId, prefix: _config.ACTION_TYPE_PREFIX, + args: args, actionId: actionId, parentActionId: parentActionId, status: status, @@ -134,22 +136,22 @@ var makeActionHandler = function makeActionHandler(Action, actionId, parentActio sourceResult: sourceResult, payload: payload, payloadSource: payloadSource - }); + }; }; }; var makeResultCallback = function makeResultCallback(responseMapper, success, error) { - return function (dispatch, getState, err, result) { + return function (dispatch, getState, err, result, args) { try { var errorMessage = (0, _helper.parseError)(err); if (errorMessage) { - return dispatch(error(errorMessage, undefined)); + return dispatch(error(errorMessage, undefined, undefined, args)); } - dispatch(success(undefined, responseMapper(result), result)); + dispatch(success(undefined, responseMapper(result), result, args)); } catch (e) { - dispatch(error(String('' + (e.message || e)), undefined)); + dispatch(error(String('' + (e.message || e)), undefined, undefined, args)); throw e; } }; @@ -183,9 +185,9 @@ var makeCallActionMethod = function makeCallActionMethod(resultCallBack) { if (actionResult instanceof Promise) { return actionResult.then(function (resp) { - return resultCallBack(dispatch, getState, false, resp); + return resultCallBack(dispatch, getState, false, resp, args); }).catch(function (err) { - return resultCallBack(dispatch, getState, err, undefined); + return resultCallBack(dispatch, getState, err, undefined, args); }); } @@ -193,19 +195,19 @@ var makeCallActionMethod = function makeCallActionMethod(resultCallBack) { actionResult = actionResult.call(undefined, dispatch, getState); if (!actionResult) { - return resultCallBack(dispatch, getState, undefined, undefined); + return resultCallBack(dispatch, getState, undefined, undefined, args); } if (actionResult instanceof Promise) { return actionResult.then(function (resp) { - return resultCallBack(dispatch, getState, false, resp); + return resultCallBack(dispatch, getState, false, resp, args); }).catch(function (err) { - return resultCallBack(dispatch, getState, err, undefined); + return resultCallBack(dispatch, getState, err, undefined, args); }); } } - return resultCallBack(dispatch, getState, false, actionResult); + return resultCallBack(dispatch, getState, false, actionResult, args); }; }; @@ -377,7 +379,7 @@ var makeAction = function makeAction(actionId, parentActionId, actionSchema, act * * @returns {Undefined} - returns None, only clear action data */ - this.action.empty = function () { + this.action.reset = function () { return function (dispatch, getState) { dispatch({ time: new Date().getTime(), @@ -389,28 +391,28 @@ var makeAction = function makeAction(actionId, parentActionId, actionSchema, act }; }; - // /** - // * Clean entity from entity reducer - // * - // * @memberOf action.makeAction.Action - // * @type {Function} - // * - // * @example - // * store.dispatch(userLoginAction.clean()) - // * - // * @returns {Undefined} - returns None, only clear entity data - // */ - // this.action.clean = () => { - // return (dispatch, getState) => { - // dispatch({ - // time: new Date().getTime(), - // type: ACTION_CLEAN_TYPE_NAME, - // prefix: ACTION_TYPE_PREFIX, - // actionId: this.actionId, - // actionSchema: this.schema - // }) - // } - // } + /** + * Remove action entity id or ids from entities reducer + * + * @memberOf action.makeAction.Action + * @type {Function} + * + * @example + * store.dispatch(userLoginAction.remove()) + * + * @returns {Undefined} - returns None, only remove entity items + */ + this.action.remove = function () { + return function (dispatch, getState) { + dispatch({ + time: new Date().getTime(), + type: _config.ACTION_REMOVE_TYPE_NAME, + prefix: _config.ACTION_TYPE_PREFIX, + actionId: _this.actionId, + actionSchema: _this.schema + }); + }; + }; return this.action; }; diff --git a/lib/config.js b/lib/config.js index c15190a..6193587 100644 --- a/lib/config.js +++ b/lib/config.js @@ -77,13 +77,13 @@ var ENTITIES_REDUCER_NAME = exports.ENTITIES_REDUCER_NAME = ACTION_TYPE_PREFIX + var ACTION_EMPTY_TYPE_NAME = exports.ACTION_EMPTY_TYPE_NAME = ACTION_TYPE_PREFIX + '-empty'; /** - * Action type name for clear entity data from entity reducer + * Action type name for delete entities from state * * @memberOf config * @const * @type {String} */ -var ACTION_CLEAN_TYPE_NAME = exports.ACTION_CLEAN_TYPE_NAME = ACTION_TYPE_PREFIX + '-clean'; +var ACTION_REMOVE_TYPE_NAME = exports.ACTION_REMOVE_TYPE_NAME = ACTION_TYPE_PREFIX + '-remove'; /** * replaced default response mapper to callback diff --git a/lib/reducer.js b/lib/reducer.js index 7f13aac..b42df68 100644 --- a/lib/reducer.js +++ b/lib/reducer.js @@ -37,7 +37,8 @@ var makeActionsReducer = function makeActionsReducer(defaultActionsState) { return state; } - var status = action.status, + var args = action.args, + status = action.status, time = action.time, actionId = action.actionId, payload = action.payload, @@ -52,8 +53,8 @@ var makeActionsReducer = function makeActionsReducer(defaultActionsState) { var entityKey = actionSchema.key; - // action.clear - if (action.type === _config.ACTION_EMPTY_TYPE_NAME) { + // action.clear || action.remove + if (action.type === _config.ACTION_EMPTY_TYPE_NAME || action.type === _config.ACTION_REMOVE_TYPE_NAME) { return state.set(actionId, (0, _immutable.fromJS)(Object.assign({ entityKey: entityKey }, actionDefaultData, { time: time }))); } @@ -68,6 +69,7 @@ var makeActionsReducer = function makeActionsReducer(defaultActionsState) { } actionState = actionState.merge({ + args: args, status: status, time: time, hasError: hasError, diff --git a/lib/selector.js b/lib/selector.js index 9e7d53c..e24cbc3 100644 --- a/lib/selector.js +++ b/lib/selector.js @@ -44,21 +44,21 @@ var getPayloadIds = function getPayloadIds(dataKey, isArray, actionState, stateK }; var makeActionDenormalizedPayload = function makeActionDenormalizedPayload(isArray, payloadIds, schema, entities) { + // return empty immutable object if (!payloadIds) { return undefined; } var result = (0, _helper.denormalize)(payloadIds, [schema], entities).filter(function (v) { return v; - }).map(function (item) { - return item.toJS(); }); + return isArray ? result : result[0]; }; var makeActionDenormalizedPayloads = function makeActionDenormalizedPayloads(isFetching, actionSchema, entities, payloadIsArray, actionDataKey, entityState, actionState) { if (!actionDataKey) { - return {}; + return undefined; } if (!entityState) { @@ -95,6 +95,7 @@ var _makeGetActionData = function _makeGetActionData(action, actionId, entityNam return Object.assign(makeDefaultActionData(), { actionId: actionId, + args: actionState.get('args'), sourceResult: actionState.get('sourceResult'), status: actionState.get('status'), time: actionState.get('time'), @@ -133,7 +134,10 @@ var getMergedActionsData = exports.getMergedActionsData = function getMergedActi }); return sortedByUpate.reduce(function (memo, item) { - return Object.assign(memo, item); + return Object.assign(memo, item, { + payload: memo.payload ? memo.payload.merge(item.payload) : item.payload, + prevPayload: memo.prevPayload ? memo.prevPayload.merge(item.prevPayload) : item.prevPayload + }); }); }); }; diff --git a/package.json b/package.json index a794cc4..63b182d 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "redux-tide", "description": "tiny factory for redux crud normalize", - "version": "0.1.4", + "version": "0.1.5", "main": "./lib/index.js", "files": [ "lib", @@ -82,7 +82,7 @@ "jsdoc": "^3.5.5", "json-server": "^0.12.1", "minami": "^1.2.3", - "mocha": "^4.1.0", + "mocha": "^5.0.0", "prettier": "^1.9.2", "raw-loader": "^0.5.1", "react": "^16.2.0", diff --git a/src/action.js b/src/action.js index 2fd9a61..74730c6 100644 --- a/src/action.js +++ b/src/action.js @@ -3,8 +3,8 @@ */ import { + ACTION_REMOVE_TYPE_NAME, ACTION_EMPTY_TYPE_NAME, - ACTION_CLEAN_TYPE_NAME, ACTION_ID_KEY, ACTION_IDS_KEY, ACTION_TYPE_PREFIX, @@ -81,9 +81,10 @@ const makeActionHandler = ( * * @param {String} error - action error text * @param {Object|Array} payloadSource - response from action result + * @param {Object|Array} args - arguments from queryBuilder * @returns {Object} - action dispatch body */ - return function(error, payloadSource, sourceResult) { + return function(error, payloadSource, sourceResult, args) { if (status === 'success' && payloadSource === undefined) { error = 'Empty payload' status = 'error' @@ -139,10 +140,11 @@ const makeActionHandler = ( * payloadSource: Object|Array * }} */ - return Object.freeze({ + return { time: new Date().getTime(), type: `${actionId}`, prefix: ACTION_TYPE_PREFIX, + args, actionId, parentActionId, status, @@ -156,22 +158,22 @@ const makeActionHandler = ( sourceResult, payload, payloadSource - }) + } } } const makeResultCallback = (responseMapper, success, error) => { - return function(dispatch, getState, err, result) { + return function(dispatch, getState, err, result, args) { try { const errorMessage = parseError(err) if (errorMessage) { - return dispatch(error(errorMessage, undefined)) + return dispatch(error(errorMessage, undefined, undefined, args)) } - dispatch(success(undefined, responseMapper(result), result)) + dispatch(success(undefined, responseMapper(result), result, args)) } catch (e) { - dispatch(error(String(`${e.message || e}`), undefined)) + dispatch(error(String(`${e.message || e}`), undefined, undefined, args)) throw e } } @@ -208,25 +210,27 @@ const makeCallActionMethod = resultCallBack => { if (actionResult instanceof Promise) { return actionResult - .then(resp => resultCallBack(dispatch, getState, false, resp)) - .catch(err => resultCallBack(dispatch, getState, err, undefined)) + .then(resp => resultCallBack(dispatch, getState, false, resp, args)) + .catch(err => resultCallBack(dispatch, getState, err, undefined, args)) } if (typeof actionResult === 'function') { actionResult = actionResult.call(this, dispatch, getState) if (!actionResult) { - return resultCallBack(dispatch, getState, undefined, undefined) + return resultCallBack(dispatch, getState, undefined, undefined, args) } if (actionResult instanceof Promise) { return actionResult - .then(resp => resultCallBack(dispatch, getState, false, resp)) - .catch(err => resultCallBack(dispatch, getState, err, undefined)) + .then(resp => resultCallBack(dispatch, getState, false, resp, args)) + .catch(err => + resultCallBack(dispatch, getState, err, undefined, args) + ) } } - return resultCallBack(dispatch, getState, false, actionResult) + return resultCallBack(dispatch, getState, false, actionResult, args) } } @@ -435,7 +439,7 @@ const makeAction = function( * * @returns {Undefined} - returns None, only clear action data */ - this.action.empty = () => { + this.action.reset = () => { return (dispatch, getState) => { dispatch({ time: new Date().getTime(), @@ -447,28 +451,28 @@ const makeAction = function( } } - // /** - // * Clean entity from entity reducer - // * - // * @memberOf action.makeAction.Action - // * @type {Function} - // * - // * @example - // * store.dispatch(userLoginAction.clean()) - // * - // * @returns {Undefined} - returns None, only clear entity data - // */ - // this.action.clean = () => { - // return (dispatch, getState) => { - // dispatch({ - // time: new Date().getTime(), - // type: ACTION_CLEAN_TYPE_NAME, - // prefix: ACTION_TYPE_PREFIX, - // actionId: this.actionId, - // actionSchema: this.schema - // }) - // } - // } + /** + * Remove action entity id or ids from entities reducer + * + * @memberOf action.makeAction.Action + * @type {Function} + * + * @example + * store.dispatch(userLoginAction.remove()) + * + * @returns {Undefined} - returns None, only remove entity items + */ + this.action.remove = () => { + return (dispatch, getState) => { + dispatch({ + time: new Date().getTime(), + type: ACTION_REMOVE_TYPE_NAME, + prefix: ACTION_TYPE_PREFIX, + actionId: this.actionId, + actionSchema: this.schema + }) + } + } return this.action } diff --git a/src/config.js b/src/config.js index a92a4b0..f7b1681 100644 --- a/src/config.js +++ b/src/config.js @@ -72,13 +72,13 @@ export const ENTITIES_REDUCER_NAME = `${ACTION_TYPE_PREFIX}-entities` export const ACTION_EMPTY_TYPE_NAME = `${ACTION_TYPE_PREFIX}-empty` /** - * Action type name for clear entity data from entity reducer + * Action type name for delete entities from state * * @memberOf config * @const * @type {String} */ -export const ACTION_CLEAN_TYPE_NAME = `${ACTION_TYPE_PREFIX}-clean` +export const ACTION_REMOVE_TYPE_NAME = `${ACTION_TYPE_PREFIX}-remove` /** * replaced default response mapper to callback diff --git a/src/index.js b/src/index.js index 12fc961..41f13e9 100644 --- a/src/index.js +++ b/src/index.js @@ -3,11 +3,11 @@ import { createReducers } from './reducer' import { denomalizeEntityItemById, getActionData, - getMergedActionsData, getEntityItemsByAction, getEntityItemsByEntityName, getEntityItemsBySchema, - getEntityReducer + getEntityReducer, + getMergedActionsData } from './selector' import { diff --git a/src/reducer.js b/src/reducer.js index 2780fb0..43b11d7 100644 --- a/src/reducer.js +++ b/src/reducer.js @@ -7,6 +7,7 @@ import { normalize } from 'normalizr' import { ACTION_EMPTY_TYPE_NAME, + ACTION_REMOVE_TYPE_NAME, ACTION_TYPE_PREFIX, ACTIONS_REDUCER_NAME, ENTITIES_REDUCER_NAME @@ -32,6 +33,7 @@ const makeActionsReducer = defaultActionsState => { } const { + args, status, time, actionId, @@ -47,8 +49,11 @@ const makeActionsReducer = defaultActionsState => { const entityKey = actionSchema.key - // action.clear - if (action.type === ACTION_EMPTY_TYPE_NAME) { + // action.clear || action.remove + if ( + action.type === ACTION_EMPTY_TYPE_NAME || + action.type === ACTION_REMOVE_TYPE_NAME + ) { return state.set( actionId, fromJS(Object.assign({ entityKey }, actionDefaultData, { time })) @@ -68,6 +73,7 @@ const makeActionsReducer = defaultActionsState => { } actionState = actionState.merge({ + args, status, time, hasError, diff --git a/src/selector.js b/src/selector.js index 1423b8d..85fc89a 100644 --- a/src/selector.js +++ b/src/selector.js @@ -46,13 +46,13 @@ const makeActionDenormalizedPayload = ( schema, entities ) => { + // return empty immutable object if (!payloadIds) { return undefined } - const result = denormalize(payloadIds, [schema], entities) - .filter(v => v) - .map(item => item.toJS()) + const result = denormalize(payloadIds, [schema], entities).filter(v => v) + return isArray ? result : result[0] } @@ -66,7 +66,7 @@ const makeActionDenormalizedPayloads = ( actionState ) => { if (!actionDataKey) { - return {} + return undefined } if (!entityState) { @@ -124,6 +124,7 @@ const _makeGetActionData = (action, actionId, entityName, actionSchema) => { makeDefaultActionData(), { actionId, + args: actionState.get('args'), sourceResult: actionState.get('sourceResult'), status: actionState.get('status'), time: actionState.get('time'), @@ -168,7 +169,14 @@ export const getMergedActionsData = (...actions) => { const sortedByUpate = actionsData.sort((a, b) => a.time - b.time) return sortedByUpate.reduce((memo, item) => { - return Object.assign(memo, item) + return Object.assign(memo, item, { + payload: memo.payload + ? memo.payload.merge(item.payload) + : item.payload, + prevPayload: memo.prevPayload + ? memo.prevPayload.merge(item.prevPayload) + : item.prevPayload + }) }) } ) diff --git a/test/action.spec.js b/test/action.spec.js index 7f75bad..678da6b 100644 --- a/test/action.spec.js +++ b/test/action.spec.js @@ -1,16 +1,14 @@ import 'should' import sinon from 'sinon' import { schema } from 'normalizr' - -require('should-sinon') - import { + createAction, makeActionHandler, - makeActionUniqId, - makeAction, - createAction + makeActionUniqId } from '../src/action' +require('should-sinon') + describe('action makeActionUniqId ', function() { it('makeActionUniqId returns uniquie ids', function() { const result = new Set([ diff --git a/test/config.spec.js b/test/config.spec.js index 6104f83..28f2406 100644 --- a/test/config.spec.js +++ b/test/config.spec.js @@ -1,24 +1,23 @@ import 'should' import sinon from 'sinon' import { schema } from 'normalizr' - -require('should-sinon') - import { - IS_TEST_ENVIRONMENT, - STATUSES, + ACTION_EMPTY_TYPE_NAME, ACTION_ID_KEY, ACTION_IDS_KEY, ACTION_TYPE_PREFIX, ACTIONS_REDUCER_NAME, ENTITIES_REDUCER_NAME, - ACTION_EMPTY_TYPE_NAME, + IS_TEST_ENVIRONMENT, setDefaultResponseMapper, - setDenormalize + setDenormalize, + STATUSES } from '../src/config' import { createAction } from '../src/action' +require('should-sinon') + describe('config is valid', function() { it('should define all required variables', function() { IS_TEST_ENVIRONMENT.should.not.be.undefined() diff --git a/test/helper.spec.js b/test/helper.spec.js index ed1bdcd..7d11602 100644 --- a/test/helper.spec.js +++ b/test/helper.spec.js @@ -1,4 +1,4 @@ -import { uniqPrefix, parseError } from '../src/helper' +import { parseError, uniqPrefix } from '../src/helper' describe('helper uniqPrefix', function() { it('created uniq prefixed', function() { diff --git a/test/selector.spec.js b/test/selector.spec.js index cf27dec..b03aadf 100644 --- a/test/selector.spec.js +++ b/test/selector.spec.js @@ -2,7 +2,7 @@ import 'should' import { schema } from 'normalizr' import { fromJS } from 'immutable' -import { ENTITIES_REDUCER_NAME, ACTIONS_REDUCER_NAME } from '../src/config' +import { ACTIONS_REDUCER_NAME, ENTITIES_REDUCER_NAME } from '../src/config' import { getActionData, getEntityItemsByAction, @@ -46,6 +46,7 @@ it('selector getActionData', function() { } const result = getActionData(action)(state) + result.payload = result.payload.toJS() result.should.be.deepEqual({ status: '', diff --git a/website/package.json b/website/package.json index 6f17121..978e5f6 100644 --- a/website/package.json +++ b/website/package.json @@ -3,32 +3,13 @@ "version": "0.1.0", "private": true, "dependencies": { - "autoprefixer": "7.1.6", - "babel-core": "6.26.0", - "babel-eslint": "7.2.3", - "babel-jest": "20.0.3", - "babel-loader": "7.1.2", - "babel-preset-react-app": "^3.1.0", - "babel-runtime": "6.26.0", + "axios": "^0.17.1", + "redux-tide": "^0.1.4", "case-sensitive-paths-webpack-plugin": "2.1.1", "chalk": "1.1.3", - "css-loader": "0.28.7", "dotenv": "4.0.0", - "eslint": "4.10.0", - "eslint-config-react-app": "^2.0.1", - "eslint-loader": "1.9.0", - "eslint-plugin-flowtype": "2.39.1", - "eslint-plugin-import": "2.8.0", - "eslint-plugin-jsx-a11y": "5.1.1", - "eslint-plugin-react": "7.4.0", - "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.5", "fs-extra": "3.0.1", "history": "^4.7.2", - "html-loader": "^0.5.4", - "html-webpack-plugin": "2.29.0", - "jest": "20.0.4", - "markdown-loader": "^2.0.2", "normalizr": "^3.2.4", "object-assign": "4.1.1", "postcss-flexbugs-fixes": "3.2.0", @@ -46,12 +27,6 @@ "redux-devtools-dock-monitor": "^1.1.3", "redux-devtools-log-monitor": "^1.4.0", "redux-thunk": "^2.2.0", - "style-loader": "0.19.0", - "sw-precache-webpack-plugin": "0.11.4", - "url-loader": "0.6.2", - "webpack": "3.8.1", - "webpack-dev-server": "2.9.4", - "webpack-manifest-plugin": "1.3.2", "whatwg-fetch": "2.0.3" }, "scripts": { @@ -59,7 +34,36 @@ "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom" }, - "devDependencies": {}, + "devDependencies": { + "codesandbox": "^1.1.14", + "autoprefixer": "7.1.6", + "babel-core": "6.26.0", + "babel-eslint": "7.2.3", + "babel-jest": "20.0.3", + "babel-loader": "7.1.2", + "babel-preset-react-app": "^3.1.0", + "babel-runtime": "6.26.0", + "eslint": "4.10.0", + "eslint-config-react-app": "^2.0.1", + "eslint-loader": "1.9.0", + "eslint-plugin-flowtype": "2.39.1", + "eslint-plugin-import": "2.8.0", + "eslint-plugin-jsx-a11y": "5.1.1", + "eslint-plugin-react": "7.4.0", + "style-loader": "0.19.0", + "sw-precache-webpack-plugin": "0.11.4", + "url-loader": "0.6.2", + "webpack": "3.8.1", + "webpack-dev-server": "2.9.4", + "webpack-manifest-plugin": "1.3.2", + "css-loader": "0.28.7", + "extract-text-webpack-plugin": "3.0.2", + "file-loader": "1.1.5", + "html-loader": "^0.5.4", + "html-webpack-plugin": "2.29.0", + "markdown-loader": "^2.0.2", + "jest": "20.0.4" + }, "jest": { "collectCoverageFrom": [ "src/**/*.{js,jsx,mjs}" diff --git a/website/public/index.html b/website/public/index.html index c016007..1900e5b 100644 --- a/website/public/index.html +++ b/website/public/index.html @@ -1,6 +1,17 @@
+ + + + + diff --git a/website/src/App.css b/website/src/App.css index 8456cbf..9eaeb28 100644 --- a/website/src/App.css +++ b/website/src/App.css @@ -1,30 +1,34 @@ .App { - text-align: center; + text-align: center; } .App-logo { - animation: App-logo-spin infinite 20s linear; - height: 80px; + animation: App-logo-spin infinite 20s linear; + height: 80px; } .App-header { - background-color: #222; - height: 150px; - padding: 20px; - color: white; + background-color: #222; + height: 150px; + padding: 20px; + color: white; } .App-title { - font-size: 1.5em; + font-size: 1.5em; } .App-intro { - font-size: large; + font-size: large; } @keyframes App-logo-spin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } .spinner { @@ -55,18 +59,23 @@ } @-webkit-keyframes sk-bouncedelay { - 0%, 80%, 100% { -webkit-transform: scale(0) } - 40% { -webkit-transform: scale(1.0) } + 0%, 80%, 100% { + -webkit-transform: scale(0) + } + 40% { + -webkit-transform: scale(1.0) + } } @keyframes sk-bouncedelay { 0%, 80%, 100% { -webkit-transform: scale(0); transform: scale(0); - } 40% { - -webkit-transform: scale(1.0); - transform: scale(1.0); - } + } + 40% { + -webkit-transform: scale(1.0); + transform: scale(1.0); + } } .spinner { @@ -97,16 +106,21 @@ } @-webkit-keyframes sk-bouncedelay { - 0%, 80%, 100% { -webkit-transform: scale(0) } - 40% { -webkit-transform: scale(1.0) } + 0%, 80%, 100% { + -webkit-transform: scale(0) + } + 40% { + -webkit-transform: scale(1.0) + } } @keyframes sk-bouncedelay { 0%, 80%, 100% { -webkit-transform: scale(0); transform: scale(0); - } 40% { - -webkit-transform: scale(1.0); - transform: scale(1.0); - } + } + 40% { + -webkit-transform: scale(1.0); + transform: scale(1.0); + } } \ No newline at end of file diff --git a/website/src/App.js b/website/src/App.js index 0a00b8f..ea0213c 100644 --- a/website/src/App.js +++ b/website/src/App.js @@ -1,23 +1,40 @@ -import React, {Component} from 'react'; -import logo from './logo.svg'; -import {Navbar, Nav, NavItem} from 'react-bootstrap' -import './App.css'; +import React, {Component} from 'react' +import logo from './logo.svg' +import {Nav, Navbar, NavItem} from 'react-bootstrap' +import './App.css' const README = require('../../README.md') const exampleName = document.location.search.replace('?ex=', '') -const PUBLIC_URL = process.env.PUBLIC_URL || '/' +const PUBLIC_URL = (document && document.location && document.location.host === 'localhost:3000') ? process.env.PUBLIC_URL || '/' : 'https://edtoken.github.io/redux-tide' -const exampleComponents = { - 'blog': require('./blog'), - 'different-entity-id': require('./different-entity-id'), - 'merged-actions-data': require('./merged-actions-data') -} +const EXAMPLES = [ + { + 'title': 'Blog example', + 'path': 'blog', + 'component': require('./blog') + }, + { + 'title': 'Different entity id', + 'path': 'different-entity-id', + 'component': require('./different-entity-id') + }, + { + 'title': 'Merged actions data', + 'path': 'merged-actions-data', + 'component': require('./merged-actions-data') + }, + { + 'title': 'Remove entity from state', + 'path': 'remove-entity-from-state', + 'component': require('./remove-entity-from-state') + } +] class App extends Component { render() { - const ExampleComponent = exampleName && exampleComponents[exampleName] ? exampleComponents[exampleName].default : undefined + const ExampleComponent = exampleName ? EXAMPLES.find(item => item.path === exampleName).component.default : undefined return ({JSON.stringify(payload, null, 2)}
-
{isFetching && {JSON.stringify({...payload.toJS(), comments: ['... Comments List ...']}, null, 2)}
}
+
+ Source code source
++ Preview in SandBox codesandbox.io +
+ +Source code source
{JSON.stringify(payload, null, 2)}+ {payload &&
{JSON.stringify({...payload.toJS(), comments: ['... Comments List ...']}, null, 2)}
}
Source code source
++ Preview in SandBox codesandbox.io +
+ +Source code source
Source code source
+ ++ Preview in SandBox codesandbox.io +
+ +Source code source
{JSON.stringify({ + title: payload ? payload.get('title') : '' + }, null, 2)}+
+ Preview in SandBox codesandbox.io +
+ +Source code source +
+ +