diff --git a/.eslintrc b/.eslintrc
index f6de202..b2f6c0f 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -26,6 +26,6 @@
}
}],
"react/prefer-stateless-function": "off",
- "react/destructuring-assignment": [false, "never"]
+ "react/destructuring-assignment": [0, "never"]
}
}
diff --git a/.travis.yml b/.travis.yml
index 75578a0..42c6852 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,8 +6,8 @@ before_script:
- cd packages/mirador3-core
- npm install
- cd ../mirador3-common
- npm install
- - cd ../mirador3-app
+ - npm install
+ - cd ../mirador3-app-base
- npm install
- cd ../..
- lerna run build
diff --git a/minimal_redux_poc/__tests__/integration/mirador/window_actions.test.js b/minimal_redux_poc/__tests__/integration/mirador/window_actions.test.js
new file mode 100644
index 0000000..e16d8b4
--- /dev/null
+++ b/minimal_redux_poc/__tests__/integration/mirador/window_actions.test.js
@@ -0,0 +1,15 @@
+describe('Window actions', () => {
+ beforeAll(async () => {
+ await page.goto('http://127.0.0.1:4488/__tests__/integration/mirador/');
+ });
+ it('opens a window and closes it', async () => {
+ await expect(page).toFill('#manifestURL', 'https://purl.stanford.edu/sn904cj3429/iiif/manifest');
+ await expect(page).toClick('#fetchBtn');
+ // TODO: Refactor the app so we get rid of the wait
+ await page.waitFor(1000);
+ await expect(page).toClick('li button');
+ await expect(page).toMatchElement('.mirador-window');
+ await expect(page).toClick('.mirador-window-close');
+ await expect(page).not.toMatchElement('.mirador-window');
+ });
+});
diff --git a/minimal_redux_poc/package-lock.json b/minimal_redux_poc/package-lock.json
index de06dea..450eea3 100644
--- a/minimal_redux_poc/package-lock.json
+++ b/minimal_redux_poc/package-lock.json
@@ -6670,9 +6670,9 @@
}
},
"merge": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.0.tgz",
- "integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz",
+ "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==",
"dev": true
},
"merge-stream": {
diff --git a/minimal_redux_poc/src/components/Window.js b/minimal_redux_poc/src/components/Window.js
new file mode 100644
index 0000000..df51142
--- /dev/null
+++ b/minimal_redux_poc/src/components/Window.js
@@ -0,0 +1,120 @@
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import fetch from 'node-fetch';
+import OpenSeaDragon from 'openseadragon';
+import ns from '../config/css-ns';
+import WindowTopBar from './WindowTopBar';
+
+/**
+ * Represents a Window in the mirador workspace
+ * @param {object} window
+ */
+class Window extends Component {
+ /**
+ * @param {Object} props [description]
+ */
+ constructor(props) {
+ super(props);
+
+ this.miradorInstanceRef = React.createRef();
+ }
+ /**
+ * React lifecycle event
+ */
+ componentDidMount() {
+ if (!this.miradorInstanceRef.current) {
+ return false;
+ }
+ const viewer = OpenSeaDragon({
+ id: this.miradorInstanceRef.current.id,
+ showNavigationControl: false,
+ });
+ const that = this;
+ fetch(`${this.props.manifest.manifestation.getSequences()[0].getCanvases()[0].getImages()[0].getResource().getServices()[0].id}/info.json`)
+ .then(response => response.json())
+ .then((json) => {
+ viewer.addTiledImage({
+ tileSource: json,
+ success: (event) => {
+ const tiledImage = event.item;
+
+ /**
+ * A callback for the tile after its drawn
+ * @param {[type]} e event object
+ */
+ const tileDrawnHandler = (e) => {
+ if (e.tiledImage === tiledImage) {
+ viewer.removeHandler('tile-drawn', tileDrawnHandler);
+ that.miradorInstanceRef.current.style.display = 'block';
+ }
+ };
+ viewer.addHandler('tile-drawn', tileDrawnHandler);
+ },
+ });
+ })
+ .catch(error => console.log(error));
+ return false;
+ }
+
+ /**
+ * Fetches IIIF thumbnail URL
+ */
+ thumbnail() {
+ const thumb = this.props.manifest.manifestation.getThumbnail() || { id: 'http://placekitten.com/200/300' };
+ return thumb.id;
+ }
+
+ /**
+ * Return style attributes
+ */
+ styleAttributes() {
+ return { width: `${this.props.window.xywh[2]}px`, height: `${this.props.window.xywh[3]}px` };
+ }
+
+ /**
+ * Renders things
+ * @param {object} props (from react/redux)
+ */
+ render() {
+ return (
+
+
+
+
+
+ );
+ }
+}
+
+Window.propTypes = {
+ window: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types
+ manifest: PropTypes.object, // eslint-disable-line react/forbid-prop-types
+};
+
+Window.defaultProps = {
+ manifest: null,
+};
+
+/**
+ * mapStateToProps - used to hook up connect to action creators
+ * @memberof Window
+ * @private
+ */
+const mapStateToProps = ({ windows, manifests }, props) => {
+ const window = windows.find(win => props.id === win.id);
+ return {
+ window,
+ manifest: manifests[window.manifestId],
+ };
+};
+
+export default connect(mapStateToProps)(Window);
diff --git a/packages/mirador3-app-base/package.json b/packages/mirador3-app-base/package.json
index 8ed8de7..3575027 100644
--- a/packages/mirador3-app-base/package.json
+++ b/packages/mirador3-app-base/package.json
@@ -66,7 +66,7 @@
"workbox-webpack-plugin": "3.6.3"
},
"scripts": {
- "dist": "node_modules/.bin/webpack --config ./config/webpack.config.dist.js",
+ "dist": "webpack --config ./config/webpack.config.dist.js",
"lint": "node_modules/.bin/eslint ./",
"start": "node scripts/start.js",
"build": "node scripts/build.js",
diff --git a/packages/mirador3-app-base/src/styles/index.scss b/packages/mirador3-app-base/src/styles/index.scss
index afa8b27..62ab946 100644
--- a/packages/mirador3-app-base/src/styles/index.scss
+++ b/packages/mirador3-app-base/src/styles/index.scss
@@ -34,11 +34,15 @@ body {
position: relative;
}
- &-window-heading {
+ &-window-top-bar {
background: linear-gradient(to bottom, rgba(0, 0, 0, .65) 0%, rgba(0, 0, 0, 0) 100%);
color: white;
position: absolute;
- z-index: 10;
+ z-index: 10;
+
+ h3 {
+ margin: 0;
+ }
}
&-osd-container {
diff --git a/packages/mirador3-common/package.json b/packages/mirador3-common/package.json
index e4c0b7b..fd190fd 100644
--- a/packages/mirador3-common/package.json
+++ b/packages/mirador3-common/package.json
@@ -10,8 +10,8 @@
"test": "npm run lint && jest -c jest.json",
"test:watch": "jest -c jest.json --watch",
"test:coverage": "jest -c jest.json --coverage",
- "build": "webpack --mode production",
- "build:watch": "node_modules/.bin/webpack --watch"
+ "build": "webpack",
+ "build:watch": "webpack --watch"
},
"dependencies": {
"css-ns": "^1.2.2",
diff --git a/packages/mirador3-common/src/components/WindowTopBar.jsx b/packages/mirador3-common/src/components/WindowTopBar.jsx
new file mode 100644
index 0000000..32d66da
--- /dev/null
+++ b/packages/mirador3-common/src/components/WindowTopBar.jsx
@@ -0,0 +1,69 @@
+import * as React from 'react';
+import { connect } from 'react-redux';
+import PropTypes from 'prop-types';
+import { actions } from 'mirador3-core';
+import { ns } from '../config/css-ns';
+
+
+/**
+ * WindowTopBar
+ */
+class WindowTopBarComponent extends React.Component {
+ /**
+ * render - description
+ * @return {type} description
+ */
+ render() {
+ return (
+
+
{this.props.manifest.manifestation.getLabel().map(label => label.value)[0]}
+
+
+ );
+ }
+}
+//
+// /**
+// * mapStateToProps - used to hook up connect to action creators
+// * @memberof Window
+// * @private
+// */
+// const mapStateToProps = ({ windows, manifests }, props) => {
+// const window = windows.find(win => props.windowId === win.id);
+// return {
+// window,
+// //
+// manifest: manifests[window.manifestId],
+// };
+// };
+
+/**
+ * mapDispatchToProps - used to hook up connect to action creators
+ * @memberof ManifestListItem
+ * @private
+ */
+const mapDispatchToProps = dispatch => ({
+ removeWindow: windowId => (
+ dispatch(actions.removeWindow(windowId))
+ ),
+});
+
+WindowTopBarComponent.propTypes = {
+ manifest: PropTypes.object, // eslint-disable-line react/forbid-prop-types
+ removeWindow: PropTypes.func.isRequired,
+ windowId: PropTypes.string.isRequired,
+};
+
+WindowTopBarComponent.defaultProps = {
+ manifest: null,
+};
+
+
+export const WindowTopBar = connect(null, mapDispatchToProps)(WindowTopBarComponent);
diff --git a/packages/mirador3-common/src/components/index.js b/packages/mirador3-common/src/components/index.js
index c98db24..cc24660 100644
--- a/packages/mirador3-common/src/components/index.js
+++ b/packages/mirador3-common/src/components/index.js
@@ -3,4 +3,5 @@ export * from './Display';
export * from './ManifestListItem';
export * from './ManifestMetadata';
export * from './Window';
+export * from './WindowTopBar';
export * from './Workspace';
diff --git a/packages/mirador3-common/src/components/test/Window.test.js b/packages/mirador3-common/src/components/test/Window.test.js
index 6daa0a9..8e98b30 100644
--- a/packages/mirador3-common/src/components/test/Window.test.js
+++ b/packages/mirador3-common/src/components/test/Window.test.js
@@ -18,7 +18,8 @@ describe('Window', () => {
});
it('returns the width and height style attribute', () => {
- expect(shallow().dive().instance().styleAttributes())
+ wrapper = shallow(, { context: { store } });
+ expect(wrapper.dive().instance().styleAttributes())
.toEqual({ width: '400px', height: '400px' });
});
@@ -26,7 +27,6 @@ describe('Window', () => {
expect(wrapper.find('.mirador-window').prop('style')).toHaveProperty('width', '400px');
expect(wrapper.find('.mirador-window').prop('style')).toHaveProperty('height', '400px');
expect(wrapper.find('div.mirador-window').length).toBe(1);
- expect(wrapper.find('div.mirador-window h3').text()).toBe('Test 24 Manifest: Image with IIIF Service - adapted with real image');
expect(wrapper.find('div.mirador-window img').prop('src')).toBe('http://placekitten.com/200/300');
});
diff --git a/packages/mirador3-common/src/components/test/WindowTopBar.test.js b/packages/mirador3-common/src/components/test/WindowTopBar.test.js
new file mode 100644
index 0000000..207120c
--- /dev/null
+++ b/packages/mirador3-common/src/components/test/WindowTopBar.test.js
@@ -0,0 +1,23 @@
+import * as React from 'react';
+import { shallow } from 'enzyme';
+import { actions, store } from 'mirador3-core';
+import { WindowTopBar } from '../WindowTopBar';
+import fixture from './fixtures/24.json';
+
+describe('Window', () => {
+ let wrapper;
+ let window;
+ beforeEach(() => {
+ store.dispatch(actions.receiveManifest('foo', fixture));
+ store.dispatch(actions.addWindow({ manifestId: 'foo' }));
+ const manifest = store.getState().manifests.foo;
+ [window] = store.getState().windows;
+ wrapper = shallow()
+ .dive();
+ });
+
+ it('renders without an error', () => {
+ expect(wrapper.find('div.mirador-window-top-bar h3').text()).toBe('Test 24 Manifest: Image with IIIF Service - adapted with real image');
+ expect(wrapper.find('button.mirador-window-close'));
+ });
+});
diff --git a/packages/mirador3-core/package.json b/packages/mirador3-core/package.json
index 450d013..aade1cd 100644
--- a/packages/mirador3-core/package.json
+++ b/packages/mirador3-core/package.json
@@ -10,8 +10,8 @@
"test": "npm run lint && jest -c jest.json",
"test:watch": "jest -c jest.json --watch",
"test:coverage": "jest -c jest.json --coverage",
- "build": "node_modules/.bin/webpack",
- "build:watch": "node_modules/.bin/webpack --watch"
+ "build": "webpack",
+ "build:watch": "webpack --watch"
},
"dependencies": {
"jest-fetch-mock": "^2.0.1",