diff --git a/__tests__/fixtures/config/export.example.json b/__tests__/fixtures/config/export.example.json index 4e7c31dcb9eada7c456c37f77d021c497ca730c6..15054c42ff63a47515a5e4fbf3c709df976c9da3 100644 --- a/__tests__/fixtures/config/export.example.json +++ b/__tests__/fixtures/config/export.example.json @@ -1,4 +1,30 @@ { + "companionWindows": { + "cw-b86f0558-6f04-4b56-ac9b-34b7e0769db3": { + "content": "info", + "default": true, + "id": "cw-b86f0558-6f04-4b56-ac9b-34b7e0769db3", + "position": "left" + }, + "cw-b15df6ac-9069-4f16-bd19-e11c6aaa3911": { + "content": "thumbnail_navigation", + "default": true, + "id": "cw-b15df6ac-9069-4f16-bd19-e11c6aaa3911", + "position": "far-bottom" + }, + "cw-c4934b3c-2411-40b1-9088-5e066276620f": { + "content": "info", + "default": true, + "id": "cw-c4934b3c-2411-40b1-9088-5e066276620f", + "position": "left" + }, + "cw-76580e14-4d7a-4ea5-84a6-5de052941a3d": { + "content": "thumbnail_navigation", + "default": true, + "id": "cw-76580e14-4d7a-4ea5-84a6-5de052941a3d", + "position": "far-bottom" + } + }, "config": { "canvasNavigation": { "height": 50, @@ -27,13 +53,104 @@ } }, "typography": { + "fontSize": 16, + "body1": { + "fontSize": "1rem", + "letterSpacing": "0em", + "lineHeight": "1.6em" + }, + "body2": { + "fontSize": "0.878rem", + "letterSpacing": "0.015em", + "lineHeight": "1.6em" + }, + "button": { + "fontSize": "0.878rem", + "letterSpacing": "0.09em", + "lineHeight": "2.25rem", + "textTransform": "uppercase" + }, + "caption": { + "fontSize": "0.772rem", + "letterSpacing": "0.033em", + "lineHeight": "1.6rem" + }, + "body1Next": { + "fontSize": "1rem", + "letterSpacing": "0em", + "lineHeight": "1.6em" + }, + "body2Next": { + "fontSize": "0.878rem", + "letterSpacing": "0.015em", + "lineHeight": "1.6em" + }, + "buttonNext": { + "fontSize": "0.878rem", + "letterSpacing": "0.09em", + "lineHeight": "2.25rem" + }, + "captionNext": { + "fontSize": "0.772rem", + "letterSpacing": "0.33em", + "lineHeight": "1.6rem" + }, + "overline": { + "fontSize": "0.678rem", + "fontWeight": 500, + "letterSpacing": "0.166em", + "lineHeight": "2em", + "textTransform": "uppercase" + }, + "h1": { + "fontSize": "2.822rem", + "letterSpacing": "-0.015em", + "lineHeight": "1.2em" + }, + "h2": { + "fontSize": "1.575rem", + "letterSpacing": "0em", + "lineHeight": "1.33em" + }, + "h3": { + "fontSize": "1.383rem", + "fontWeight": 300, + "letterSpacing": "0em", + "lineHeight": "1.33em" + }, + "h4": { + "fontSize": "1.215rem", + "letterSpacing": "0.007em", + "lineHeight": "1.45em" + }, + "h5": { + "fontSize": "1.138rem", + "letterSpacing": "0.005em", + "lineHeight": "1.55em" + }, + "h6": { + "fontSize": "1.067rem", + "fontWeight": 400, + "letterSpacing": "0.01em", + "lineHeight": "1.6em" + }, + "subtitle1": { + "fontSize": "0.937rem", + "letterSpacing": "0.015em", + "lineHeight": "1.6em", + "fontWeight": 300 + }, + "subtitle2": { + "fontSize": "0.878rem", + "fontWeight": 500, + "letterSpacing": "0.02em", + "lineHeight": "1.75em" + }, "useNextVariants": true }, - "overrides": { - "MuiInput": { - "input": { - "backgroundColor": "LightGray" - } + "props": { + "MuiButtonBase": { + "disableTouchRipple": true } } }, @@ -42,8 +159,11 @@ "de": "Deutsch", "en": "English" }, + "displayAllAnnotations": false, "translations": {}, "window": { + "allowClose": true, + "allowMaximize": true, "defaultView": "single" }, "windows": [ @@ -57,7 +177,7 @@ } ], "thumbnailNavigation": { - "defaultPosition": "bottom", + "defaultPosition": "far-bottom", "height": 150, "width": 100 }, @@ -102,47 +222,77 @@ } }, "viewers": { - "window-32450374-dd2c-455e-83f6-ce0e70d21c5c": { - "x": 2696, - "y": 4079, - "zoom": 0.0001107429053115508 + "window-404c667d-e1e0-4ae7-aaf2-98e08bb627bd": { + "x": 1205.5, + "y": 1686, + "zoom": 0.00021117049395471312 }, - "window-65138dce-d192-484d-8445-b579f5ee14d6": { - "x": 1129.5, - "y": 1275, - "zoom": 0.0002890035037322365 + "window-f48761a4-4388-4ddd-aff6-9a331410aad3": { + "x": 2217.999999999988, + "y": 3193.5865262629163, + "zoom": 0.00010301562691749936 } }, "windows": { - "window-65138dce-d192-484d-8445-b579f5ee14d6": { - "id": "window-65138dce-d192-484d-8445-b579f5ee14d6", - "canvasIndex": 2, + "window-404c667d-e1e0-4ae7-aaf2-98e08bb627bd": { + "canvasIndex": 4, "collectionIndex": 0, - "manifestId": "https://iiif.harvardartmuseums.org/manifests/object/299843", - "rangeId": null, - "thumbnailNavigationPosition": "bottom", - "width": 400, + "companionWindowIds": [ + "cw-b86f0558-6f04-4b56-ac9b-34b7e0769db3", + "cw-b15df6ac-9069-4f16-bd19-e11c6aaa3911" + ], + "displayAllAnnotations": false, "height": 400, - "x": 2700, - "y": 2700, - "companionWindowIds": [], + "id": "window-404c667d-e1e0-4ae7-aaf2-98e08bb627bd", + "manifestId": "https://wellcomelibrary.org/iiif/b18035723/manifest", + "maximized": false, + "rangeId": null, "rotation": null, - "view": "single" + "selectedAnnotations": {}, + "sideBarPanel": "info", + "thumbnailNavigationId": "cw-b15df6ac-9069-4f16-bd19-e11c6aaa3911", + "view": "single", + "width": 400, + "x": 200, + "y": 200 }, - "window-32450374-dd2c-455e-83f6-ce0e70d21c5c": { - "id": "window-32450374-dd2c-455e-83f6-ce0e70d21c5c", - "canvasIndex": 0, + "window-f48761a4-4388-4ddd-aff6-9a331410aad3": { + "canvasIndex": 1, "collectionIndex": 0, - "manifestId": "https://iiif.bodleian.ox.ac.uk/iiif/manifest/e32a277e-91e2-4a6d-8ba6-cc4bad230410.json", - "rangeId": null, - "thumbnailNavigationPosition": "off", - "width": 400, + "companionWindowIds": [ + "cw-c4934b3c-2411-40b1-9088-5e066276620f", + "cw-76580e14-4d7a-4ea5-84a6-5de052941a3d" + ], + "displayAllAnnotations": false, "height": 400, - "x": 2700, - "y": 2700, - "companionWindowIds": [], + "id": "window-f48761a4-4388-4ddd-aff6-9a331410aad3", + "manifestId": "https://demos.biblissima.fr/iiif/metadata/florus-dispersus/manifest.json", + "maximized": false, + "rangeId": null, "rotation": null, - "view": "single" + "selectedAnnotations": {}, + "sideBarPanel": "info", + "thumbnailNavigationId": "cw-76580e14-4d7a-4ea5-84a6-5de052941a3d", + "view": "single", + "width": 400, + "x": 230, + "y": 250 } + }, + "workspace": { + "exposeModeOn": false, + "height": 5000, + "viewportPosition": { + "x": 0, + "y": 0 + }, + "width": 5000, + "layout": { + "direction": "row", + "first": "window-404c667d-e1e0-4ae7-aaf2-98e08bb627bd", + "second": "window-f48761a4-4388-4ddd-aff6-9a331410aad3" + }, + "focusedWindowId": "window-f48761a4-4388-4ddd-aff6-9a331410aad3", + "isWorkspaceAddVisible": false } } \ No newline at end of file diff --git a/src/components/WorkspaceImport.js b/src/components/WorkspaceImport.js index 32cbf77d2bf5d9ee09dc738f6a6bf96a1e56e06b..5004373f519ec6e707bdfb40d4b7546d70c7f8c5 100644 --- a/src/components/WorkspaceImport.js +++ b/src/components/WorkspaceImport.js @@ -3,7 +3,7 @@ import Dialog from '@material-ui/core/Dialog'; import DialogContent from '@material-ui/core/DialogContent'; import DialogTitle from '@material-ui/core/DialogTitle'; import PropTypes from 'prop-types'; -import { TextField } from '@material-ui/core'; +import { Input } from '@material-ui/core'; import Button from '@material-ui/core/Button'; /** @@ -42,11 +42,13 @@ export class WorkspaceImport extends Component { const { configImportValue } = this.state; event.preventDefault(); try { + console.log(configImportValue); const configJSON = JSON.parse(configImportValue); importConfig(configJSON); } catch (ex) { + console.log(ex); const { addError } = this.props; - addError(ex.message); + addError(ex.toString()); } } @@ -59,10 +61,10 @@ export class WorkspaceImport extends Component { handleClose, open, t, } = this.props; return ( - <Dialog id="workspace-settings" open={open} onClose={handleClose}> - <DialogTitle id="form-dialog-title">{t('import')}</DialogTitle> + <Dialog id="workspace-import" open={open} onClose={handleClose}> + <DialogTitle id="workspace-import-title">{t('import')}</DialogTitle> <DialogContent> - <TextField rows="15" multiline variant="filled" onChange={this.handleChange} /> + <Input id="workspace-import-input" rows="15" multiline variant="filled" onChange={this.handleChange} /> <div> <Button onClick={this.handleClick}> {t('importWorkspace')} diff --git a/src/components/WorkspaceMenu.js b/src/components/WorkspaceMenu.js index 5ef00799f928d893048bd59efe16ccc531cab30b..daf3f9cde15ec6acbb7059117ad074f82be4193d 100644 --- a/src/components/WorkspaceMenu.js +++ b/src/components/WorkspaceMenu.js @@ -161,6 +161,7 @@ export class WorkspaceMenu extends Component { </MenuItem> <MenuItem aria-haspopup="true" + id="workspace-menu-import" onClick={(e) => { this.handleMenuItemClick('importWorkspace', e); handleClose(e); }} aria-owns={exportWorkspace.AnchorEl ? 'workspace-import' : undefined} > @@ -196,6 +197,7 @@ export class WorkspaceMenu extends Component { /> <WorkspaceImport open={Boolean(importWorkspace.open)} + container={container} handleClose={this.handleMenuItemClose('importWorkspace')} /> </> diff --git a/src/state/actions/workspace.js b/src/state/actions/workspace.js index 59ded76b827a96f8ac1f6f86532232a2b56596cd..b7f0cc5a3b4683c375680be46110cc28e3027eea 100644 --- a/src/state/actions/workspace.js +++ b/src/state/actions/workspace.js @@ -102,7 +102,6 @@ export function toggleWorkspaceExposeMode() { * importWorkspace - action creator */ export function importWorkspace(stateExport) { - // debugger; return (dispatch, getState) => { const { viewers } = stateExport || {}; const { companionWindows } = stateExport || {}; @@ -117,7 +116,7 @@ export function importWorkspace(stateExport) { const exWins = values(getState().windows); const exWinCnt = exWins.length > imWins.length ? imWins.length : exWins.length; - /* first do window independent stuff */ + /* do window independent stuff at first */ dispatch(importConfig(stateExport.config)); getState().workspace.exposeModeOn !== exposeModeOn && dispatch(toggleWorkspaceExposeMode()); dispatch(setWorkspaceViewportDimensions({ height, width })); @@ -134,27 +133,29 @@ export function importWorkspace(stateExport) { const exIds = slice(exWins, 0, exWinCnt).map((exWin) => { const imWin = imWins.shift(); const viewer = viewers[imWin.id]; - dispatch(fetchManifest(imWin.manifestId)); - /* - remove exisiting companionWindows, except the ones marked as default - */ + /* remove exisiting companionWindows, except the ones marked as default */ exWin.companionWindowIds - .filter(cwId => !getState().companionWindows[cwId].default) - .map(cwId => dispatch(removeCompanionWindow(exWin.id, cwId))); + .filter(cwId1 => !getState().companionWindows[cwId1].default) + .map(cwId2 => dispatch(removeCompanionWindow(exWin.id, cwId2))); - /* update the window */ + /* update window */ dispatch(updateWindow(exWin.id, omit(imWin, 'id', 'companionWindowIds', 'thumbnailNavigationId'))); /* update default companionWindows */ exWin.companionWindowIds - .filter(cwId => companionWindows[cwId].default) - .map(cwId => dispatch(updateCompanionWindow(exWin.id, cwId, companionWindows[cwId]))); - - /* create non-default companionWindows */ + // eslint-disable-next-line max-len + .filter(cwId => getState().companionWindows[cwId] && getState().companionWindows[cwId].default) + .map((cwId) => { + const newCw = values(companionWindows) + .find(cw => cw.default && cw.content === getState().companionWindows[cwId].content); + return dispatch(updateCompanionWindow(exWin.id, cwId, omit(newCw, 'id'))); + }); + + /* create non-default companion windows */ imWin.companionWindowIds .filter(cwId => !companionWindows[cwId].default) - .map(cwId => dispatch(addCompanionWindow(exWin.id, { ...omit(companionWindows[cwId], 'id') }))); + .map(cwId => dispatch(addCompanionWindow(exWin.id, omit(companionWindows[cwId], 'id')))); dispatch(updateViewport(exWin.id, viewer)); return exWin.id; }); @@ -166,11 +167,20 @@ export function importWorkspace(stateExport) { dispatch(fetchManifest(imWin.manifestId)); dispatch(addWindow(omit(imWin, ['companionWindowIds', 'thumbnailNavigationId']))); dispatch(updateViewport(imWin.id, viewer)); - /* create companion windows */ + + /* create non-default companion windows */ values(companionWindows) .filter(cw => !cw.default) .map(cw => dispatch(addCompanionWindow(imWin.id, { ...omit(cw, 'id') }, {}))); + /* update default companion windows */ + values(companionWindows) + .filter(cw => cw.default) + .map((cwNew) => { + const cwOld = values(getState().companionWindows) + .find(el => el.content === cwNew.content); + return dispatch(updateCompanionWindow(imWin.id, cwOld.id, omit(cwNew, 'id'))); + }); return imWin.id; });