UNPKG

dash-core-components

Version:

Core component suite for Dash

212 lines (207 loc) 6.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _ramda = require("ramda"); var _react = _interopRequireDefault(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } /** * Abstraction for the memory storage_type to work the same way as local/session * * Each memory Store component get it's own MemStore. */ class MemStore { constructor() { this._data = {}; this._modified = -1; } getItem(key) { return this._data[key]; } setItem(key, value) { this._data[key] = value; this.setModified(key); } removeItem(key) { delete this._data[key]; this.setModified(key); } // noinspection JSUnusedLocalSymbols setModified(_) { this._modified = Date.now(); } // noinspection JSUnusedLocalSymbols getModified(_) { return this._modified; } } /** * Abstraction for local/session storage_type. * * Single instances for localStorage, sessionStorage */ class WebStore { constructor(storage) { this._storage = storage; } getItem(key) { try { return JSON.parse(this._storage.getItem(key)); } catch (e) { // in case we somehow got a non-JSON value in storage, // just ignore it. return null; } } setItem(key, value) { this._storage.setItem(key, JSON.stringify(value)); this.setModified(key); } removeItem(key) { this._storage.removeItem(key); this._storage.removeItem("".concat(key, "-timestamp")); } setModified(key) { this._storage.setItem("".concat(key, "-timestamp"), Date.now()); } getModified(key) { return Number.parseInt(this._storage.getItem("".concat(key, "-timestamp")), 10) || -1; } } /** * Easily keep data on the client side with this component. * The data is not inserted in the DOM. * Data can be in memory, localStorage or sessionStorage. * The data will be kept with the id as key. */ class Store extends _react.default.Component { constructor(props) { super(props); if (props.storage_type === 'local') { this._backstore = new WebStore(window.localStorage); } else if (props.storage_type === 'session') { this._backstore = new WebStore(window.sessionStorage); } else if (props.storage_type === 'memory') { this._backstore = new MemStore(); } this.onStorageChange = this.onStorageChange.bind(this); } onStorageChange(e) { var _this$props = this.props, id = _this$props.id, setProps = _this$props.setProps; if (e.key === id && setProps && e.newValue !== e.oldValue) { setProps({ data: JSON.parse(e.newValue), modified_timestamp: this._backstore.getModified(id) }); } } UNSAFE_componentWillMount() { var _this$props2 = this.props, setProps = _this$props2.setProps, id = _this$props2.id, data = _this$props2.data, storage_type = _this$props2.storage_type; if (storage_type !== 'memory') { window.addEventListener('storage', this.onStorageChange); } var old = this._backstore.getItem(id); if ((0, _ramda.isNil)(old) && !(0, _ramda.isNil)(data)) { // Initial data mount this._backstore.setItem(id, data); setProps({ modified_timestamp: this._backstore.getModified(id) }); return; } if (!(0, _ramda.equals)(old, data)) { setProps({ data: old, modified_timestamp: this._backstore.getModified(id) }); } } componentWillUnmount() { if (this.props.storage_type !== 'memory') { window.removeEventListener('storage', this.onStorageChange); } } componentDidUpdate() { var _this$props3 = this.props, data = _this$props3.data, id = _this$props3.id, clear_data = _this$props3.clear_data, setProps = _this$props3.setProps; if (clear_data) { this._backstore.removeItem(id); setProps({ clear_data: false, data: null, modified_timestamp: this._backstore.getModified(id) }); return; } var old = this._backstore.getItem(id); // Only set the data if it's not the same data. // If the new data is undefined, we got here by overwriting the entire // component with a new copy that has no `data` specified - so pull back // out the old value. // Note: this still allows you to set data to null if (!(0, _ramda.equals)(data, old)) { if (data === undefined) { setProps({ data: old }); } else { this._backstore.setItem(id, data); setProps({ modified_timestamp: this._backstore.getModified(id) }); } } } render() { return null; } } exports.default = Store; Store.defaultProps = { storage_type: 'memory', clear_data: false, modified_timestamp: -1 }; Store.propTypes = { /** * The ID of this component, used to identify dash components * in callbacks. The ID needs to be unique across all of the * components in an app. */ id: _propTypes.default.string.isRequired, /** * The type of the web storage. * * memory: only kept in memory, reset on page refresh. * local: window.localStorage, data is kept after the browser quit. * session: window.sessionStorage, data is cleared once the browser quit. */ storage_type: _propTypes.default.oneOf(['local', 'session', 'memory']), /** * The stored data for the id. */ data: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.array, _propTypes.default.number, _propTypes.default.string, _propTypes.default.bool]), /** * Set to true to remove the data contained in `data_key`. */ clear_data: _propTypes.default.bool, /** * The last time the storage was modified. */ modified_timestamp: _propTypes.default.number, /** * Dash-assigned callback that gets fired when the value changes. */ setProps: _propTypes.default.func };