UNPKG

redux-resource-plugins

Version:

Official plugins for Redux Resource

428 lines (305 loc) 11.2 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('redux-resource')) : typeof define === 'function' && define.amd ? define(['exports', 'redux-resource'], factory) : (factory((global.ReduxResourcePlugins = {}),global.ReduxResource)); }(this, (function (exports,reduxResource) { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var defineProperty = function (obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var toConsumableArray = function (arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } else { return Array.from(arr); } }; // End actions can be failed, succeeded, or idle. Idle should be dispatched // when the request is aborted (with a status code of 0). var createEndActions = [reduxResource.actionTypes.CREATE_RESOURCES_FAILED, reduxResource.actionTypes.CREATE_RESOURCES_SUCCEEDED, reduxResource.actionTypes.CREATE_RESOURCES_IDLE]; var readEndActions = [reduxResource.actionTypes.READ_RESOURCES_FAILED, reduxResource.actionTypes.READ_RESOURCES_SUCCEEDED, reduxResource.actionTypes.READ_RESOURCES_IDLE]; var updateEndActions = [reduxResource.actionTypes.UPDATE_RESOURCES_FAILED, reduxResource.actionTypes.UPDATE_RESOURCES_SUCCEEDED, reduxResource.actionTypes.UPDATE_RESOURCES_IDLE]; var deleteEndActions = [reduxResource.actionTypes.DELETE_RESOURCES_FAILED, reduxResource.actionTypes.DELETE_RESOURCES_SUCCEEDED, reduxResource.actionTypes.DELETE_RESOURCES_IDLE]; // This sets a new meta property on resource and request metadata: `statusCode`. // This will be equal to the last status code for a request function httpStatusCodes(resourceType) { return function (state, action) { var typeToCheck = action.resourceType || action.resourceName; if (typeToCheck !== resourceType) { return state; } var isCreateEndAction = createEndActions.indexOf(action.type) !== -1; var isReadEndAction = readEndActions.indexOf(action.type) !== -1; var isUpdateEndAction = updateEndActions.indexOf(action.type) !== -1; var isDeleteEndAction = deleteEndActions.indexOf(action.type) !== -1; if (!isCreateEndAction && !isReadEndAction && !isUpdateEndAction && !isDeleteEndAction) { return state; } var statusCode = typeof action.statusCode === 'number' ? action.statusCode : null; var resources = action.resources; var request = void 0; var naiveKey = action.requestKey || action.request; if (naiveKey && typeof naiveKey === 'string') { request = naiveKey; } var newRequests = void 0, newMeta = void 0, idList = void 0; if (resources) { idList = resources.map(function (r) { if ((typeof r === 'undefined' ? 'undefined' : _typeof(r)) === 'object') { return r.id; } else { return r; } }); } else { idList = []; } if (request) { var existingRequest = state.requests[request] || {}; newRequests = _extends({}, state.requests, defineProperty({}, request, _extends({}, existingRequest, { statusCode: statusCode }))); } else { newRequests = _extends({}, state.requests); } if (idList.length) { var metaPrefix = void 0; if (isCreateEndAction) { metaPrefix = 'create'; } else if (isReadEndAction) { metaPrefix = 'read'; } else if (isUpdateEndAction) { metaPrefix = 'update'; } else if (isDeleteEndAction) { metaPrefix = 'delete'; } newMeta = reduxResource.setResourceMeta({ meta: state.meta, newMeta: defineProperty({}, metaPrefix + 'StatusCode', statusCode), resources: idList, mergeMeta: true }); } else { newMeta = state.meta; } return _extends({}, state, { requests: newRequests, meta: newMeta }); }; } // This plugin adds support for "compound documents," or including multiple // resource types in a single action. function includedResources(resourceType) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return function (state, action) { var initialResourceMeta = options.initialResourceMeta; var includedResources = action.includedResources, mergeMeta = action.mergeMeta, mergeResources = action.mergeResources, type = action.type; var isReadType = type === reduxResource.actionTypes.READ_RESOURCES_SUCCEEDED; var isCreateType = type === reduxResource.actionTypes.CREATE_RESOURCES_SUCCEEDED; var isUpdateType = type === reduxResource.actionTypes.UPDATE_RESOURCES_SUCCEEDED; if (!isReadType && !isCreateType && !isUpdateType) { return state; } // If this action has no includedResources, then there is nothing to do if (!includedResources) { return state; } // If there are no included resources for this slice, then we do nothing var includedResourceList = includedResources[resourceType]; if (!includedResourceList) { return state; } var resources = reduxResource.upsertResources(state.resources, includedResourceList, mergeResources); var newMeta = { readStatus: reduxResource.requestStatuses.SUCCEEDED }; if (isCreateType) { newMeta.createStatus = reduxResource.requestStatuses.SUCCEEDED; } else if (isUpdateType) { newMeta.updateStatus = reduxResource.requestStatuses.SUCCEEDED; } var meta = reduxResource.setResourceMeta({ resources: includedResourceList, meta: state.meta, newMeta: newMeta, initialResourceMeta: initialResourceMeta, mergeMeta: mergeMeta }); return _extends({}, state, { meta: meta, resources: resources }); }; } var actionTypes$1 = { SELECT_RESOURCES: 'SELECT_RESOURCES', DESELECT_RESOURCES: 'DESELECT_RESOURCES', CLEAR_SELECTED_RESOURCES: 'CLEAR_SELECTED_RESOURCES' }; var initialState = { selectedIds: [] }; function selectResources(resourceType, resources) { return { type: actionTypes$1.SELECT_RESOURCES, resourceType: resourceType, resources: resources }; } function deselectResources(resourceType, resources) { return { type: actionTypes$1.DESELECT_RESOURCES, resourceType: resourceType, resources: resources }; } function clearSelectedResources(resourceType) { return { type: actionTypes$1.CLEAR_SELECTED_RESOURCES, resourceType: resourceType }; } function selection(resourceType) { return function (state, action) { // Ignore actions that were dispatched for another resource type var typeToUse = action.resourceType || action.resourceName; if (typeToUse !== resourceType) { return state; } var selectedIds = void 0, resourceIds = void 0; var resources = action.resources || []; if (action.type === actionTypes$1.SELECT_RESOURCES) { selectedIds = [].concat(toConsumableArray(state.selectedIds)) || []; resourceIds = resources.map(function (r) { return (typeof r === 'undefined' ? 'undefined' : _typeof(r)) === 'object' ? r.id : r; }); var selectedIdsSet = new Set(selectedIds); resourceIds.forEach(function (id) { if (!selectedIdsSet.has(id)) { selectedIds.push(id); } }); return _extends({}, state, { selectedIds: selectedIds }); } else if (action.type === actionTypes$1.DESELECT_RESOURCES) { selectedIds = [].concat(toConsumableArray(state.selectedIds)) || []; resourceIds = resources.map(function (r) { return (typeof r === 'undefined' ? 'undefined' : _typeof(r)) === 'object' ? r.id : r; }); var resourceIdsSet = new Set(resourceIds); return _extends({}, state, { selectedIds: selectedIds.filter(function (id) { return !resourceIdsSet.has(id); }) }); } else if (action.type === actionTypes$1.CLEAR_SELECTED_RESOURCES) { return _extends({}, state, { selectedIds: [] }); } return state; }; } selection.actionTypes = actionTypes$1; selection.selectResources = selectResources; selection.deselectResources = deselectResources; selection.clearSelectedResources = clearSelectedResources; selection.initialState = initialState; var actionTypes$2 = { RESET_RESOURCE: 'RESET_RESOURCE' }; function resetResource(resourceType) { var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, request = _ref.request, requestKey = _ref.requestKey, list = _ref.list; return { type: 'RESET_RESOURCE', resourceType: resourceType, request: request, requestKey: requestKey, list: list }; } function reset(resourceType) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return function (state, action) { var typeToUse = action.resourceType || action.resourceName; if (action.type !== actionTypes$2.RESET_RESOURCE || typeToUse !== resourceType) { return state; } var request = action.request, requestKey = action.requestKey, list = action.list; var keyToUse = requestKey || request; if (!keyToUse && !list) { return _extends({ resources: {}, meta: {}, lists: {}, requests: {} }, options.initialState); } var newState = _extends({}, state); if (keyToUse) { var existingRequest = state.requests[keyToUse]; var requestName = existingRequest && existingRequest.requestName; var newRequest = { resourceType: typeToUse, requestKey: keyToUse, ids: [], status: reduxResource.requestStatuses.IDLE }; if (requestName) { newRequest.requestName = requestName; } newState.requests = _extends({}, state.requests, defineProperty({}, keyToUse, newRequest)); } if (list) { newState.lists = _extends({}, state.lists, defineProperty({}, list, [])); } return newState; }; } reset.actionTypes = actionTypes$2; reset.resetResource = resetResource; exports.httpStatusCodes = httpStatusCodes; exports.selection = selection; exports.reset = reset; exports.includedResources = includedResources; Object.defineProperty(exports, '__esModule', { value: true }); })));