Skip to content
Snippets Groups Projects
Unverified Commit 52031fa9 authored by Jack Reed's avatar Jack Reed Committed by GitHub
Browse files

Merge pull request #3138 from ProjectMirador/3137-configurable-export-state

Make the workspace export configurable
parents 0074fd8f 967d5b3d
Branches
Tags
No related merge requests found
......@@ -2,7 +2,6 @@ import React from 'react';
import { shallow } from 'enzyme';
import Dialog from '@material-ui/core/Dialog';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import Snackbar from '@material-ui/core/Snackbar';
import { CopyToClipboard } from 'react-copy-to-clipboard';
import { WorkspaceExport } from '../../../src/components/WorkspaceExport';
......@@ -27,7 +26,7 @@ describe('WorkspaceExport', () => {
<WorkspaceExport
open
handleClose={handleClose}
state={mockState}
exportableState={mockState}
/>,
);
});
......
......@@ -89,9 +89,9 @@ describe('manifests reducer', () => {
});
});
it('should handle IMPORT_MIRADOR_STATE setting to clean state', () => {
expect(manifestsReducer({}, {
expect(manifestsReducer({ old: 'stuff' }, {
state: { manifests: { new: 'stuff' } },
type: ActionTypes.IMPORT_MIRADOR_STATE,
})).toEqual({});
})).toEqual({ new: 'stuff' });
});
});
......@@ -7,6 +7,7 @@ import {
getThemeDirection,
getConfig,
getRequestsConfig,
getExportableState,
} from '../../../src/state/selectors';
describe('getConfig', () => {
......@@ -16,6 +17,23 @@ describe('getConfig', () => {
});
});
describe('getExportableState', () => {
it('returns whole stems', () => {
const a = { some: 'value' };
const b = [1, 2, 3];
const state = { a, b, config: { export: { a: true, b: true } } };
expect(getExportableState(state)).toEqual({ a, b });
});
it('filters out parts of stems', () => {
const f = {
a: 1, b: 2, c: 3, d: 4,
};
const state = { config: { export: { f: { filter: ([k, v]) => (v % 2) === 0 } } }, f };
expect(getExportableState(state)).toEqual({ f: { b: 2, d: 4 } });
});
});
describe('getLanguagesFromConfigWithCurrent', () => {
it('returns an array of objects with locale, label, and current properties', () => {
const state = {
......
......@@ -38,25 +38,10 @@ export class WorkspaceExport extends Component {
/**
* @private
*/
exportableState() {
const { state } = this.props;
const {
companionWindows,
config,
elasticLayout,
viewers,
windows,
workspace,
} = state;
exportedState() {
const { exportableState } = this.props;
return JSON.stringify({
companionWindows,
config,
elasticLayout,
viewers,
windows,
workspace,
}, null, 2);
return JSON.stringify(exportableState, null, 2);
}
......@@ -70,8 +55,6 @@ export class WorkspaceExport extends Component {
} = this.props;
const { copied } = this.state;
const exportableState = this.exportableState();
if (copied) {
return (
<Snackbar
......@@ -108,14 +91,14 @@ export class WorkspaceExport extends Component {
<ScrollIndicatedDialogContent>
{children}
<pre>
{exportableState}
{this.exportedState()}
</pre>
</ScrollIndicatedDialogContent>
<DialogActions>
<Button onClick={this.handleClose}>{t('cancel')}</Button>
<CopyToClipboard
onCopy={this.onCopy}
text={exportableState}
text={this.exportedState()}
>
<Button variant="contained" color="primary">{t('copy')}</Button>
</CopyToClipboard>
......@@ -128,9 +111,9 @@ export class WorkspaceExport extends Component {
WorkspaceExport.propTypes = {
children: PropTypes.node,
container: PropTypes.object, // eslint-disable-line react/forbid-prop-types
exportableState: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
handleClose: PropTypes.func.isRequired,
open: PropTypes.bool,
state: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
t: PropTypes.func,
};
......
......@@ -319,5 +319,17 @@ export default {
preserveImageSizeOnResize: true,
preserveViewport: true,
showNavigationControl: false,
},
export: {
catalog: true,
companionWindows: true,
config: true,
elasticLayout: true,
layers: true,
// filter out anything re-retrievable:
manifests: { filter: ([id, value]) => !id.startsWith('http') },
viewers: true,
windows: true,
workspace: true,
}
};
......@@ -3,13 +3,18 @@ import { connect } from 'react-redux';
import { withTranslation } from 'react-i18next';
import { withPlugins } from '../extend/withPlugins';
import { WorkspaceExport } from '../components/WorkspaceExport';
import {
getExportableState,
} from '../state/selectors';
/**
* mapStateToProps - to hook up connect
* @memberof Workspace
* @private
*/
const mapStateToProps = state => ({ state });
const mapStateToProps = state => ({
exportableState: getExportableState(state),
});
const enhance = compose(
withTranslation(),
......
......@@ -44,7 +44,7 @@ export const manifestsReducer = (state = {}, action) => {
return object;
}, {});
case ActionTypes.IMPORT_MIRADOR_STATE:
return {};
return action.state.manifests || {};
default: return state;
}
};
......@@ -6,6 +6,33 @@ export function getConfig(state) {
return (state && state.config) || {};
}
/**
* Extract an exportable version of state using the configuration from the config.
*/
export function getExportableState(state) {
const exportConfig = getConfig(state).export;
return Object.entries(exportConfig).reduce(
(acc, [stem, value]) => {
if (value === true) {
acc[stem] = state[stem];
} else if (value.filter) {
acc[stem] = Object.entries(state[stem])
.filter(value.filter)
.reduce(
(stemAcc, [k, v]) => {
stemAcc[k] = v; // eslint-disable-line no-param-reassign
return stemAcc;
},
{},
);
}
return acc;
},
{},
);
}
/**
* Return languages from config (in state) and indicate which is currently set
* @param {object} state
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment