diff --git a/e2e/tests/functional/plugins/notebook/notebookSnapshots.e2e.spec.js b/e2e/tests/functional/plugins/notebook/notebookSnapshots.e2e.spec.js
index 00c3f01f8c..e0d76dc53f 100644
--- a/e2e/tests/functional/plugins/notebook/notebookSnapshots.e2e.spec.js
+++ b/e2e/tests/functional/plugins/notebook/notebookSnapshots.e2e.spec.js
@@ -24,9 +24,11 @@
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks.
*/
+const fs = require('fs').promises;
const { test, expect } = require('../../../../pluginFixtures');
-// const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
-// const nbUtils = require('../../../../helper/notebookUtils');
+const { createDomainObjectWithDefaults } = require('../../../../appActions');
+
+const NOTEBOOK_NAME = 'Notebook';
test.describe('Snapshot Menu tests', () => {
test.fixme(
@@ -161,3 +163,57 @@ test.describe('Snapshot Container tests', () => {
}
);
});
+
+test.describe('Snapshot image tests', () => {
+ test.beforeEach(async ({ page }) => {
+ //Navigate to baseURL
+ await page.goto('./', { waitUntil: 'domcontentloaded' });
+
+ // Create Notebook
+ await createDomainObjectWithDefaults(page, {
+ type: NOTEBOOK_NAME
+ });
+ });
+
+ test('Can drop an image onto a notebook and create a new entry', async ({ page }) => {
+ const imageData = await fs.readFile('src/images/favicons/favicon-96x96.png');
+ const imageArray = new Uint8Array(imageData);
+ const fileData = Array.from(imageArray);
+
+ const dropTransfer = await page.evaluateHandle((data) => {
+ const dataTransfer = new DataTransfer();
+ const file = new File([new Uint8Array(data)], 'favicon-96x96.png', { type: 'image/png' });
+ dataTransfer.items.add(file);
+ return dataTransfer;
+ }, fileData);
+
+ await page.dispatchEvent('.c-notebook__drag-area', 'drop', { dataTransfer: dropTransfer });
+
+ // be sure that entry was created
+ await expect(page.getByText('favicon-96x96.png')).toBeVisible();
+
+ // click on image (need to click twice to focus)
+ await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).click();
+ await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).click();
+
+ // expect large image to be displayed
+ await expect(page.getByRole('dialog').getByText('favicon-96x96.png')).toBeVisible();
+
+ await page.getByLabel('Close').click();
+
+ // drop another image onto the entry
+ await page.dispatchEvent('.c-snapshots', 'drop', { dataTransfer: dropTransfer });
+
+ // expect two embedded images now
+ expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(2);
+
+ await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
+
+ await page.getByRole('menuitem', { name: /Remove This Embed/ }).click();
+
+ await page.getByRole('button', { name: 'Ok', exact: true }).click();
+
+ // expect one embedded image now as we deleted the other
+ expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(1);
+ });
+});
diff --git a/src/plugins/notebook/components/Notebook.vue b/src/plugins/notebook/components/Notebook.vue
index 277c6988df..d56228e922 100644
--- a/src/plugins/notebook/components/Notebook.vue
+++ b/src/plugins/notebook/components/Notebook.vue
@@ -165,6 +165,7 @@ import { isNotebookViewType, RESTRICTED_NOTEBOOK_TYPE } from '../notebook-consta
import {
addNotebookEntry,
createNewEmbed,
+ createNewImageEmbed,
getEntryPosById,
getNotebookEntries,
mutateObject,
@@ -615,12 +616,31 @@ export default {
this.openmct.editor.cancel();
}
},
- async dropOnEntry(event) {
- event.preventDefault();
- event.stopImmediatePropagation();
+ async dropOnEntry(dropEvent) {
+ dropEvent.preventDefault();
+ dropEvent.stopImmediatePropagation();
- const snapshotId = event.dataTransfer.getData('openmct/snapshot/id');
- if (snapshotId.length) {
+ const localImageDropped = dropEvent.dataTransfer.files?.[0]?.type.includes('image');
+ const imageUrl = dropEvent.dataTransfer.getData('URL');
+ const snapshotId = dropEvent.dataTransfer.getData('openmct/snapshot/id');
+ if (localImageDropped) {
+ // local image dropped from disk (file)
+ const imageData = dropEvent.dataTransfer.files[0];
+ const imageEmbed = await createNewImageEmbed(imageData, this.openmct, imageData?.name);
+ this.newEntry(imageEmbed);
+ } else if (imageUrl) {
+ // remote image dropped (URL)
+ try {
+ const response = await fetch(imageUrl);
+ const imageData = await response.blob();
+ const imageEmbed = await createNewImageEmbed(imageData, this.openmct);
+ this.newEntry(imageEmbed);
+ } catch (error) {
+ this.openmct.notifications.alert(`Unable to add image: ${error.message} `);
+ console.error(`Problem embedding remote image`, error);
+ }
+ } else if (snapshotId.length) {
+ // snapshot object
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
this.newEntry(snapshot.embedObject);
this.snapshotContainer.removeSnapshot(snapshotId);
@@ -631,22 +651,21 @@ export default {
namespace
);
saveNotebookImageDomainObject(this.openmct, notebookImageDomainObject);
+ } else {
+ // plain domain object
+ const data = dropEvent.dataTransfer.getData('openmct/domain-object-path');
+ const objectPath = JSON.parse(data);
+ const bounds = this.openmct.time.bounds();
+ const snapshotMeta = {
+ bounds,
+ link: null,
+ objectPath,
+ openmct: this.openmct
+ };
+ const embed = await createNewEmbed(snapshotMeta);
- return;
+ this.newEntry(embed);
}
-
- const data = event.dataTransfer.getData('openmct/domain-object-path');
- const objectPath = JSON.parse(data);
- const bounds = this.openmct.time.bounds();
- const snapshotMeta = {
- bounds,
- link: null,
- objectPath,
- openmct: this.openmct
- };
- const embed = await createNewEmbed(snapshotMeta);
-
- this.newEntry(embed);
},
focusOnEntryId() {
if (!this.focusEntryId) {
diff --git a/src/plugins/notebook/components/NotebookEmbed.vue b/src/plugins/notebook/components/NotebookEmbed.vue
index 3d928a5b55..46de1d9ca9 100644
--- a/src/plugins/notebook/components/NotebookEmbed.vue
+++ b/src/plugins/notebook/components/NotebookEmbed.vue
@@ -27,13 +27,13 @@
@mouseleave="hideToolTip"
>
-
![]()
+
-
{{
- embed.name
- }}
+
+ {{ embed.name }}
+