diff --git a/apis/nucleus/src/__tests__/viz.spec.js b/apis/nucleus/src/__tests__/viz.spec.js
index 0ffc51a63..21a578fca 100644
--- a/apis/nucleus/src/__tests__/viz.spec.js
+++ b/apis/nucleus/src/__tests__/viz.spec.js
@@ -22,17 +22,20 @@ describe('viz', () => {
let setSnOptions;
let setSnContext;
let takeSnapshot;
+ let exportImage;
before(() => {
sandbox = sinon.createSandbox();
unmount = sandbox.spy();
setSnOptions = sandbox.spy();
setSnContext = sandbox.spy();
takeSnapshot = sandbox.spy();
+ exportImage = sandbox.spy();
cellRef = {
current: {
setSnOptions,
setSnContext,
takeSnapshot,
+ exportImage,
},
};
glue = sandbox.stub().returns([unmount, cellRef]);
@@ -61,6 +64,10 @@ describe('viz', () => {
it('should have a setTemporaryProperties method', () => {
expect(api.setTemporaryProperties).to.be.a('function');
});
+
+ it('should have an exportImage method', () => {
+ expect(api.exportImage).to.be.a('function');
+ });
});
describe('mounting', () => {
@@ -133,4 +140,11 @@ describe('viz', () => {
expect(cellRef.current.takeSnapshot).to.have.been.calledWithExactly();
});
});
+
+ describe('export', () => {
+ it('should export image', async () => {
+ api.exportImage();
+ expect(cellRef.current.exportImage).to.have.been.calledWithExactly();
+ });
+ });
});
diff --git a/apis/nucleus/src/components/Cell.jsx b/apis/nucleus/src/components/Cell.jsx
index 179ea71c7..9318dd253 100644
--- a/apis/nucleus/src/components/Cell.jsx
+++ b/apis/nucleus/src/components/Cell.jsx
@@ -233,29 +233,15 @@ const Cell = forwardRef(({ nebulaContext, model, initialSnContext, initialSnOpti
setSnContext,
setSnOptions,
async takeSnapshot() {
- const snapshot = {
- ...layout,
- snapshotData: {
- object: {
- size: {
- w: contentRect.width,
- h: contentRect.height,
- },
- },
- },
- };
+ const { width, height } = cellRef.current.getBoundingClientRect();
+
+ // clone layout to avoid mutation
+ let clonedLayout = JSON.parse(JSON.stringify(layout));
if (typeof state.sn.component.setSnapshotData === 'function') {
- return (await state.sn.component.setSnapshotData(snapshot)) || snapshot;
+ clonedLayout = (await state.sn.component.setSnapshotData(clonedLayout)) || clonedLayout;
}
- return snapshot;
- },
- async exportImage() {
- if (!nebulaContext.snapshot.capture) {
- throw new Error('Nebula has not been configured with snapshot.capture');
- }
- const lyt = await this.takeSnapshot(); // eslint-disable-line
- const { width, height } = cellRef.current.getBoundingClientRect();
- const s = {
+ return {
+ key: String(+Date.now()),
meta: {
language: translator.language(),
theme: theme.name,
@@ -265,10 +251,15 @@ const Cell = forwardRef(({ nebulaContext, model, initialSnContext, initialSnOpti
height: Math.round(height),
},
},
- layout: lyt,
+ layout: clonedLayout,
};
-
- return nebulaContext.snapshot.capture(s);
+ },
+ async exportImage() {
+ if (!nebulaContext.snapshot.capture) {
+ throw new Error('Nebula has not been configured with snapshot.capture');
+ }
+ const snapshot = await this.takeSnapshot(); // eslint-disable-line
+ return nebulaContext.snapshot.capture(snapshot);
},
}),
[state.sn, contentRect, layout, theme.name]
diff --git a/apis/nucleus/src/components/__tests__/cell.spec.jsx b/apis/nucleus/src/components/__tests__/cell.spec.jsx
index fcb92f4fd..31f8b64f4 100644
--- a/apis/nucleus/src/components/__tests__/cell.spec.jsx
+++ b/apis/nucleus/src/components/__tests__/cell.spec.jsx
@@ -75,7 +75,7 @@ describe(' | ', () => {
await act(async () => {
renderer = create(
- s }}>
+ s, language: () => 'sv' }}>
| ', () => {
});
global.window.addEventListener.callArg(1);
const snapshot = await cellRef.current.takeSnapshot();
+ const { key } = snapshot;
+ delete snapshot.key;
+ expect(key).to.be.a('string');
expect(snapshot).to.deep.equal({
- visualization: 'sn',
- snapshotData: { object: { size: { w: 300, h: 400 } } },
+ layout: {
+ visualization: 'sn',
+ },
+ meta: {
+ language: 'sv',
+ theme: 'dark',
+ size: {
+ height: 400,
+ width: 300,
+ },
+ },
});
});
@@ -460,7 +472,7 @@ describe(' | ', () => {
});
global.window.addEventListener.callArg(1);
const snapshot = await cellRef.current.takeSnapshot();
- expect(snapshot).to.deep.equal({
+ expect(snapshot.layout).to.deep.equal({
foo: 'bar',
});
});
diff --git a/apis/nucleus/src/viz.js b/apis/nucleus/src/viz.js
index 91814888b..0520e94eb 100644
--- a/apis/nucleus/src/viz.js
+++ b/apis/nucleus/src/viz.js
@@ -112,13 +112,15 @@ export default function viz({ model, context: nebulaContext } = {}) {
setSnContext(ctx);
return api;
},
+ exportImage() {
+ return cellRef.current.exportImage();
+ },
+
+ // DEBUG MODE ?
+ // TODO - decide if this method is useful as part of public API
takeSnapshot() {
- // TODO - decide if this method is useful at all
return cellRef.current.takeSnapshot();
},
- exportImage(settings) {
- return cellRef.current.exportImage(settings);
- },
// QVisualization API
// close() {},
diff --git a/commands/serve/web/components/Cell.jsx b/commands/serve/web/components/Cell.jsx
index 88ad7af18..638d192cf 100644
--- a/commands/serve/web/components/Cell.jsx
+++ b/commands/serve/web/components/Cell.jsx
@@ -74,15 +74,19 @@ export default function({ id, expandable, minHeight }) {
});
} else {
const containerSize = vizRef.current.el.getBoundingClientRect();
- vizRef.current.viz.exportImage().then(res => {
- if (res && res.url) {
- const key = /\/([A-z0-9_]+)$/.exec(res.url)[1];
- window.open(
- `/render?snapshot=${key}`,
- 'snapshot',
- `height=${Math.round(containerSize.height)},width=${Math.round(containerSize.width)}`
- );
- }
+ vizRef.current.viz.takeSnapshot().then(snapshot => {
+ fetch('/njs/snapshot', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(snapshot),
+ });
+ window.open(
+ `/render?snapshot=${snapshot.key}`,
+ 'snapshot',
+ `height=${Math.round(containerSize.height)},width=${Math.round(containerSize.width)}`
+ );
});
}
},
diff --git a/commands/serve/web/eRender.js b/commands/serve/web/eRender.js
index 9c6ff9b56..9d3037b93 100644
--- a/commands/serve/web/eRender.js
+++ b/commands/serve/web/eRender.js
@@ -85,9 +85,12 @@ async function renderSnapshot() {
},
],
});
- snapshooter({
- nucleus: n,
- element,
+
+ window.onHotChange(supernova.name, async () => {
+ snapshooter({
+ nucleus: n,
+ element,
+ });
});
}