Fix: Asset preservation (#25359)

* fix: proptype error

* fix: correct proptype checking

* fix: add assets placeholder to initial state

* chore: add history formatting function

* fix: load workpad assets when ids change

this causes the correct assets to be used
This commit is contained in:
Joe Fleming 2018-11-08 09:20:28 -07:00 committed by GitHub
parent 80073b4555
commit c79fac22fa
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 9 deletions

View file

@ -157,7 +157,7 @@ export class AssetManager extends React.PureComponent {
cannot be determined at this time.
</p>
</EuiText>
<EuiFlexGrid responsive="false" columns={4}>
<EuiFlexGrid responsive={false} columns={4}>
{this.props.assets.map(this.renderAsset)}
</EuiFlexGrid>
</EuiModalBody>

View file

@ -29,8 +29,5 @@ export const Error = ({ payload }) => {
};
Error.propTypes = {
payload: PropTypes.shape({
info: PropTypes.object.isRequired,
error: PropTypes.object.isRequired,
}).isRequired,
payload: PropTypes.object.isRequired,
};

View file

@ -10,6 +10,7 @@ import { getDefaultWorkpad } from './defaults';
export const getInitialState = path => {
const state = {
app: {}, // Kibana stuff in here
assets: {}, // assets end up here
transient: {
canUserWrite: true,
fullscreen: false,

View file

@ -8,9 +8,17 @@ import { isEqual } from 'lodash';
import { routes } from '../../apps';
import { historyProvider } from '../../lib/history_provider';
import { routerProvider } from '../../lib/router_provider';
import { get as fetchWorkpad } from '../../lib/workpad_service';
import { restoreHistory, undoHistory, redoHistory } from '../actions/history';
import { initializeWorkpad } from '../actions/workpad';
import { setAssets } from '../actions/assets';
import { isAppReady } from '../selectors/app';
import { getWorkpad } from '../selectors/workpad';
function getHistoryState(state) {
// this is what gets written to browser history
return state.persistent;
}
export const historyMiddleware = ({ dispatch, getState }) => {
// iterate over routes, injecting redux to action handlers
@ -52,7 +60,19 @@ export const historyMiddleware = ({ dispatch, getState }) => {
// only restore the history on popState events with state
// this only happens when using back/forward with popState objects
if (isBrowserNav) return dispatch(restoreHistory(historyState));
if (isBrowserNav) {
// TODO: oof, this sucks. we can't just shove assets into history state because
// firefox is limited to 640k (wat!). so, when we see that the workpad id is changing,
// we instead just restore the assets, which ensures the overall state is correct.
// there must be a better way to handle history though...
const currentWorkpadId = getWorkpad(getState()).id;
if (currentWorkpadId !== historyState.workpad.id) {
const newWorkpad = await fetchWorkpad(historyState.workpad.id);
dispatch(setAssets(newWorkpad.assets));
}
return dispatch(restoreHistory(historyState));
}
// execute route action on pushState and popState events
if (isUrlChange) return await router.parse(pathname);
@ -99,14 +119,17 @@ export const historyMiddleware = ({ dispatch, getState }) => {
// if app switched from not ready to ready, replace current state
// this allows the back button to work correctly all the way to first page load
if (!isAppReady(oldState) && isAppReady(newState)) {
history.replace(newState.persistent);
history.replace(getHistoryState(newState));
return;
}
// if the persistent state changed, push it into the history
if (!isEqual(newState.persistent, oldState.persistent)) {
const oldHistoryState = getHistoryState(oldState);
const historyState = getHistoryState(newState);
if (!isEqual(historyState, oldHistoryState)) {
// if there are pending route changes, just replace current route (to avoid extra back/forth history entries)
const useReplaceState = handlerState.pendingCount !== 0;
useReplaceState ? history.replace(newState.persistent) : history.push(newState.persistent);
useReplaceState ? history.replace(historyState) : history.push(historyState);
}
};
};