Compare commits
	
		
			28 Commits
		
	
	
		
			6820
			...
			nb-embed-e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					98836b256f | ||
| 
						 | 
					4dee94480c | ||
| 
						 | 
					17fee67e08 | ||
| 
						 | 
					3bd12a1db4 | ||
| 
						 | 
					3e45b2ccd7 | ||
| 
						 | 
					4b08aa93e6 | ||
| 
						 | 
					e48f419db7 | ||
| 
						 | 
					f6e0224099 | ||
| 
						 | 
					df3b8b55d9 | ||
| 
						 | 
					fcf950cf43 | ||
| 
						 | 
					54f06d36a5 | ||
| 
						 | 
					a742c35ff9 | ||
| 
						 | 
					332540598b | ||
| 
						 | 
					06d1efc008 | ||
| 
						 | 
					d196cafb9c | ||
| 
						 | 
					081eeb8a1f | ||
| 
						 | 
					97245781e5 | ||
| 
						 | 
					ede591d768 | ||
| 
						 | 
					945f220727 | ||
| 
						 | 
					bd9ed3de87 | ||
| 
						 | 
					eb50e93cd9 | ||
| 
						 | 
					b72bad16d9 | ||
| 
						 | 
					a4d2290274 | ||
| 
						 | 
					9a3806b117 | ||
| 
						 | 
					ba26e38837 | ||
| 
						 | 
					29a747405e | ||
| 
						 | 
					305d566ee7 | ||
| 
						 | 
					95e6a5b3ad | 
@@ -24,8 +24,6 @@
 | 
			
		||||
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
// FIXME: Remove this eslint exception once tests are implemented
 | 
			
		||||
// eslint-disable-next-line no-unused-vars
 | 
			
		||||
const { test, expect } = require('../../../../pluginFixtures');
 | 
			
		||||
const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
 | 
			
		||||
const nbUtils = require('../../../../helper/notebookUtils');
 | 
			
		||||
@@ -266,70 +264,3 @@ test.describe('Notebook entry tests', () => {
 | 
			
		||||
    test.fixme('new entries persist through navigation events without save', async ({ page }) => {});
 | 
			
		||||
    test.fixme('previous and new entries can be deleted', async ({ page }) => {});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.describe('Snapshot Menu tests', () => {
 | 
			
		||||
    test.fixme('When no default notebook is selected, Snapshot Menu dropdown should only have a single option', async ({ page }) => {
 | 
			
		||||
        // There should be no default notebook
 | 
			
		||||
        // Clear default notebook if exists using `localStorage.setItem('notebook-storage', null);`
 | 
			
		||||
        // refresh page
 | 
			
		||||
        // Click on 'Notebook Snaphot Menu'
 | 
			
		||||
        // 'save to Notebook Snapshots' should be only option there
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('When default notebook is updated selected, Snapshot Menu dropdown should list it as the newest option', async ({ page }) => {
 | 
			
		||||
        // Create 2a notebooks
 | 
			
		||||
        // Set Notebook A as Default
 | 
			
		||||
        // Open Snapshot Menu and note that Notebook A is listed
 | 
			
		||||
        // Close Snapshot Menu
 | 
			
		||||
        // Set Default Notebook to Notebook B
 | 
			
		||||
        // Open Snapshot Notebook and note that Notebook B is listed
 | 
			
		||||
        // Select Default Notebook Option and verify that Snapshot is added to Notebook B
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Can add Snapshots via Snapshot Menu and details are correct', async ({ page }) => {
 | 
			
		||||
        //Note this should be a visual test, too
 | 
			
		||||
        // Create Telemetry object
 | 
			
		||||
        // Create A notebook with many pages and sections.
 | 
			
		||||
        // Set page and section defaults to be between first and last of many. i.e. 3 of 5
 | 
			
		||||
        // Navigate to Telemetry object
 | 
			
		||||
        // Select Default Notebook Option and verify that Snapshot is added to Notebook A
 | 
			
		||||
        // Verify Snapshot Details appear correctly
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Snapshots adjust time conductor', async ({ page }) => {
 | 
			
		||||
        // Create Telemetry object
 | 
			
		||||
        // Set Telemetry object's timeconductor to Fixed time with Start and Endtimes are recorded
 | 
			
		||||
        // Embed Telemetry object into notebook
 | 
			
		||||
        // Set Time Conductor to Local clock
 | 
			
		||||
        // Click into embedded telemetry object and verify object appears with same fixed time from record
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.describe('Snapshot Container tests', () => {
 | 
			
		||||
    test.fixme('5 Snapshots can be added to a container', async ({ page }) => {});
 | 
			
		||||
    test.fixme('5 Snapshots can be added to a container and Deleted with Delete All action', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot can be Deleted from Container', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot can be Previewed from Container', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot Container can be open and closed', async ({ page }) => {});
 | 
			
		||||
    test.fixme('Can add object to Snapshot container and pull into notebook and create a new entry', async ({ page }) => {
 | 
			
		||||
        //Create Notebook
 | 
			
		||||
        //Create Telemetry Object
 | 
			
		||||
        //From Telemetry Object, use 'save to Notebook Snapshots'
 | 
			
		||||
        //Snapshots indicator should blink, click on it to view snapshots
 | 
			
		||||
        //Navigate to Notebook
 | 
			
		||||
        //Drag and Drop onto droppable area for new entry
 | 
			
		||||
        //New Entry created with given snapshot added
 | 
			
		||||
        //Snapshot removed from container?
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Can add object to Snapshot container and pull into notebook and existing entry', async ({ page }) => {
 | 
			
		||||
        //Create Notebook
 | 
			
		||||
        //Create Telemetry Object
 | 
			
		||||
        //From Telemetry Object, use 'save to Notebook Snapshots'
 | 
			
		||||
        //Snapshots indicator should blink, click on it to view snapshots
 | 
			
		||||
        //Navigate to Notebook
 | 
			
		||||
        //Drag and Drop into exiting entry
 | 
			
		||||
        //Existing Entry updated with given snapshot
 | 
			
		||||
        //Snapshot removed from container?
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Verify Embedded options for PNG, JPG, and Annotate work correctly', async ({ page }) => {
 | 
			
		||||
        //Add snapshot to container
 | 
			
		||||
        //Verify PNG, JPG, and Annotate buttons work correctly
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,134 @@
 | 
			
		||||
/*****************************************************************************
 | 
			
		||||
 * Open MCT, Copyright (c) 2014-2022, United States Government
 | 
			
		||||
 * as represented by the Administrator of the National Aeronautics and Space
 | 
			
		||||
 * Administration. All rights reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT is licensed under the Apache License, Version 2.0 (the
 | 
			
		||||
 * "License"); you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 * http://www.apache.org/licenses/LICENSE-2.0.
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
			
		||||
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
			
		||||
 * License for the specific language governing permissions and limitations
 | 
			
		||||
 * under the License.
 | 
			
		||||
 *
 | 
			
		||||
 * Open MCT includes source code licensed under additional open source
 | 
			
		||||
 * licenses. See the Open Source Licenses file (LICENSES.md) included with
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks.
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
const { test, expect } = require('../../../../pluginFixtures');
 | 
			
		||||
// const { expandTreePaneItemByName, createDomainObjectWithDefaults } = require('../../../../appActions');
 | 
			
		||||
// const nbUtils = require('../../../../helper/notebookUtils');
 | 
			
		||||
 | 
			
		||||
test.describe('Snapshot Menu tests', () => {
 | 
			
		||||
    test.fixme('When no default notebook is selected, Snapshot Menu dropdown should only have a single option', async ({ page }) => {
 | 
			
		||||
        // There should be no default notebook
 | 
			
		||||
        // Clear default notebook if exists using `localStorage.setItem('notebook-storage', null);`
 | 
			
		||||
        // refresh page
 | 
			
		||||
        // Click on 'Notebook Snaphot Menu'
 | 
			
		||||
        // 'save to Notebook Snapshots' should be only option there
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('When default notebook is updated selected, Snapshot Menu dropdown should list it as the newest option', async ({ page }) => {
 | 
			
		||||
        // Create 2a notebooks
 | 
			
		||||
        // Set Notebook A as Default
 | 
			
		||||
        // Open Snapshot Menu and note that Notebook A is listed
 | 
			
		||||
        // Close Snapshot Menu
 | 
			
		||||
        // Set Default Notebook to Notebook B
 | 
			
		||||
        // Open Snapshot Notebook and note that Notebook B is listed
 | 
			
		||||
        // Select Default Notebook Option and verify that Snapshot is added to Notebook B
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Can add Snapshots via Snapshot Menu and details are correct', async ({ page }) => {
 | 
			
		||||
        //Note this should be a visual test, too
 | 
			
		||||
        // Create Telemetry object
 | 
			
		||||
        // Create A notebook with many pages and sections.
 | 
			
		||||
        // Set page and section defaults to be between first and last of many. i.e. 3 of 5
 | 
			
		||||
        // Navigate to Telemetry object
 | 
			
		||||
        // Select Default Notebook Option and verify that Snapshot is added to Notebook A
 | 
			
		||||
        // Verify Snapshot Details appear correctly
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Snapshots adjust time conductor', async ({ page }) => {
 | 
			
		||||
        // Create Telemetry object
 | 
			
		||||
        // Set Telemetry object's timeconductor to Fixed time with Start and Endtimes are recorded
 | 
			
		||||
        // Embed Telemetry object into notebook
 | 
			
		||||
        // Set Time Conductor to Local clock
 | 
			
		||||
        // Click into embedded telemetry object and verify object appears with same fixed time from record
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
test.describe('Snapshot Container tests', () => {
 | 
			
		||||
    test.beforeEach(async ({ page }) => {
 | 
			
		||||
        //Navigate to baseURL
 | 
			
		||||
        await page.goto('./', { waitUntil: 'networkidle' });
 | 
			
		||||
 | 
			
		||||
        // Create Notebook
 | 
			
		||||
        // const notebook = await createDomainObjectWithDefaults(page, {
 | 
			
		||||
        //     type: 'Notebook',
 | 
			
		||||
        //     name: "Test Notebook"
 | 
			
		||||
        // });
 | 
			
		||||
        // // Create Overlay Plot
 | 
			
		||||
        // const snapShotObject = await createDomainObjectWithDefaults(page, {
 | 
			
		||||
        //     type: 'Overlay Plot',
 | 
			
		||||
        //     name: "Dropped Overlay Plot"
 | 
			
		||||
        // });
 | 
			
		||||
 | 
			
		||||
        await page.getByRole('button', { name: ' Snapshot ' }).click();
 | 
			
		||||
        await page.getByRole('menuitem', { name: ' Save to Notebook Snapshots' }).click();
 | 
			
		||||
        await page.getByRole('button', { name: 'Show' }).click();
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('5 Snapshots can be added to a container', async ({ page }) => {});
 | 
			
		||||
    test.fixme('5 Snapshots can be added to a container and Deleted with Delete All action', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot can be Deleted from Container with 3 dot action menu', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot can be Viewed, Annotated, display deleted, and saved from Container with 3 dot action menu', async ({ page }) => {
 | 
			
		||||
        await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
 | 
			
		||||
        await page.getByRole('menuitem', { name: ' View Snapshot' }).click();
 | 
			
		||||
        await expect(page.locator('.c-overlay__outer')).toBeVisible();
 | 
			
		||||
        await page.getByTitle('Annotate').click();
 | 
			
		||||
        await expect(page.locator('#snap-annotation-canvas')).toBeVisible();
 | 
			
		||||
        await page.getByRole('button', { name: '' }).click();
 | 
			
		||||
        // await expect(page.locator('#snap-annotation-canvas')).not.toBeVisible();
 | 
			
		||||
        await page.getByRole('button', { name: 'Save' }).click();
 | 
			
		||||
        await page.getByRole('button', { name: 'Done' }).click();
 | 
			
		||||
        //await expect(await page.locator)
 | 
			
		||||
    });
 | 
			
		||||
    test('A snapshot can be Quick Viewed from Container with 3 dot action menu', async ({ page }) => {
 | 
			
		||||
        await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
 | 
			
		||||
        await page.getByRole('menuitem', { name: 'Quick View' }).click();
 | 
			
		||||
        await expect(page.locator('.c-overlay__outer')).toBeVisible();
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('A snapshot can be Navigated To from Container with 3 dot action menu', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot can be Navigated To Item in Time from Container with 3 dot action menu', async ({ page }) => {});
 | 
			
		||||
    test.fixme('A snapshot Container can be open and closed', async ({ page }) => {});
 | 
			
		||||
    test.fixme('Can add object to Snapshot container and pull into notebook and create a new entry', async ({ page }) => {
 | 
			
		||||
        //Create Notebook
 | 
			
		||||
        //Create Telemetry Object
 | 
			
		||||
        //From Telemetry Object, use 'save to Notebook Snapshots'
 | 
			
		||||
        //Snapshots indicator should blink, click on it to view snapshots
 | 
			
		||||
        //Navigate to Notebook
 | 
			
		||||
        //Drag and Drop onto droppable area for new entry
 | 
			
		||||
        //New Entry created with given snapshot added
 | 
			
		||||
        //Snapshot removed from container?
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Can add object to Snapshot container and pull into notebook and existing entry', async ({ page }) => {
 | 
			
		||||
        //Create Notebook
 | 
			
		||||
        //Create Telemetry Object
 | 
			
		||||
        //From Telemetry Object, use 'save to Notebook Snapshots'
 | 
			
		||||
        //Snapshots indicator should blink, click on it to view snapshots
 | 
			
		||||
        //Navigate to Notebook
 | 
			
		||||
        //Drag and Drop into exiting entry
 | 
			
		||||
        //Existing Entry updated with given snapshot
 | 
			
		||||
        //Snapshot removed from container?
 | 
			
		||||
    });
 | 
			
		||||
    test.fixme('Verify Embedded options for PNG, JPG, and Annotate work correctly', async ({ page }) => {
 | 
			
		||||
        //Add snapshot to container
 | 
			
		||||
        //Verify PNG, JPG, and Annotate buttons work correctly
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
@@ -152,7 +152,7 @@ test.describe('Restricted Notebook with a page locked and with an embed @addInit
 | 
			
		||||
 | 
			
		||||
    test('Allows embeds to be deleted if page unlocked @addInit', async ({ page }) => {
 | 
			
		||||
        // Click .c-ne__embed__name .c-popup-menu-button
 | 
			
		||||
        await page.locator('.c-ne__embed__name .c-popup-menu-button').click(); // embed popup menu
 | 
			
		||||
        await page.locator('.c-ne__embed__name .c-icon-button').click(); // embed popup menu
 | 
			
		||||
 | 
			
		||||
        const embedMenu = page.locator('body >> .c-menu');
 | 
			
		||||
        await expect(embedMenu).toContainText('Remove This Embed');
 | 
			
		||||
@@ -161,7 +161,7 @@ test.describe('Restricted Notebook with a page locked and with an embed @addInit
 | 
			
		||||
    test('Disallows embeds to be deleted if page locked @addInit', async ({ page }) => {
 | 
			
		||||
        await lockPage(page);
 | 
			
		||||
        // Click .c-ne__embed__name .c-popup-menu-button
 | 
			
		||||
        await page.locator('.c-ne__embed__name .c-popup-menu-button').click(); // embed popup menu
 | 
			
		||||
        await page.locator('.c-ne__embed__name .c-icon-button').click(); // embed popup menu
 | 
			
		||||
 | 
			
		||||
        const embedMenu = page.locator('body >> .c-menu');
 | 
			
		||||
        await expect(embedMenu).not.toContainText('Remove This Embed');
 | 
			
		||||
 
 | 
			
		||||
@@ -12,14 +12,15 @@
 | 
			
		||||
            <a
 | 
			
		||||
                class="c-ne__embed__link"
 | 
			
		||||
                :class="embed.cssClass"
 | 
			
		||||
                @click="changeLocation"
 | 
			
		||||
                @click="navigateToItemInTime"
 | 
			
		||||
            >{{ embed.name }}</a>
 | 
			
		||||
            <PopupMenu :popup-menu-items="popupMenuItems" />
 | 
			
		||||
            <button
 | 
			
		||||
                class="c-ne__embed__actions c-icon-button icon-3-dots"
 | 
			
		||||
                title="More options"
 | 
			
		||||
                @click.prevent.stop="showMenuItems($event)"
 | 
			
		||||
            ></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div
 | 
			
		||||
            v-if="embed.snapshot"
 | 
			
		||||
            class="c-ne__embed__time"
 | 
			
		||||
        >
 | 
			
		||||
        <div class="c-ne__embed__time">
 | 
			
		||||
            {{ createdOn }}
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@@ -32,17 +33,14 @@ import PreviewAction from '../../../ui/preview/PreviewAction';
 | 
			
		||||
import RemoveDialog from '../utils/removeDialog';
 | 
			
		||||
import PainterroInstance from '../utils/painterroInstance';
 | 
			
		||||
import SnapshotTemplate from './snapshot-template.html';
 | 
			
		||||
import objectPathToUrl from '@/tools/url';
 | 
			
		||||
 | 
			
		||||
import { updateNotebookImageDomainObject } from '../utils/notebook-image';
 | 
			
		||||
import ImageExporter from '../../../exporters/ImageExporter';
 | 
			
		||||
 | 
			
		||||
import PopupMenu from './PopupMenu.vue';
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
    components: {
 | 
			
		||||
        PopupMenu
 | 
			
		||||
    },
 | 
			
		||||
    inject: ['openmct', 'snapshotContainer'],
 | 
			
		||||
    props: {
 | 
			
		||||
        embed: {
 | 
			
		||||
@@ -72,7 +70,7 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            popupMenuItems: []
 | 
			
		||||
            menuActions: []
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
@@ -88,37 +86,88 @@ export default {
 | 
			
		||||
    watch: {
 | 
			
		||||
        isLocked(value) {
 | 
			
		||||
            if (value === true) {
 | 
			
		||||
                let index = this.popupMenuItems.findIndex((item) => item.id === 'removeEmbed');
 | 
			
		||||
                let index = this.menuActions.findIndex((item) => item.id === 'removeEmbed');
 | 
			
		||||
 | 
			
		||||
                this.$delete(this.popupMenuItems, index);
 | 
			
		||||
                this.$delete(this.menuActions, index);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.addPopupMenuItems();
 | 
			
		||||
    async mounted() {
 | 
			
		||||
        this.objectPath = [];
 | 
			
		||||
        await this.setEmbedObjectPath();
 | 
			
		||||
        this.addMenuActions();
 | 
			
		||||
        this.imageExporter = new ImageExporter(this.openmct);
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        addPopupMenuItems() {
 | 
			
		||||
            const removeEmbed = {
 | 
			
		||||
                id: 'removeEmbed',
 | 
			
		||||
                cssClass: 'icon-trash',
 | 
			
		||||
                name: this.removeActionString,
 | 
			
		||||
                callback: this.getRemoveDialog.bind(this)
 | 
			
		||||
            };
 | 
			
		||||
            const preview = {
 | 
			
		||||
                id: 'preview',
 | 
			
		||||
                cssClass: 'icon-eye-open',
 | 
			
		||||
                name: 'Preview',
 | 
			
		||||
                callback: this.previewEmbed.bind(this)
 | 
			
		||||
        showMenuItems(event) {
 | 
			
		||||
            const x = event.x;
 | 
			
		||||
            const y = event.y;
 | 
			
		||||
 | 
			
		||||
            const menuOptions = {
 | 
			
		||||
                menuClass: 'c-ne__embed__actions-menu',
 | 
			
		||||
                placement: this.openmct.menus.menuPlacement.TOP_RIGHT
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.popupMenuItems = [preview];
 | 
			
		||||
            this.openmct.menus.showSuperMenu(x, y, this.menuActions, menuOptions);
 | 
			
		||||
        },
 | 
			
		||||
        addMenuActions() {
 | 
			
		||||
            if (this.embed.snapshot) {
 | 
			
		||||
                const viewSnapshot = {
 | 
			
		||||
                    id: 'viewSnapshot',
 | 
			
		||||
                    cssClass: 'icon-camera',
 | 
			
		||||
                    name: 'View Snapshot',
 | 
			
		||||
                    description: 'View the snapshot image taken in the form of a jpeg.',
 | 
			
		||||
                    onItemClicked: () => this.openSnapshot()
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
            if (!this.isLocked) {
 | 
			
		||||
                this.popupMenuItems.unshift(removeEmbed);
 | 
			
		||||
                this.menuActions = [viewSnapshot];
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const navigateToItem = {
 | 
			
		||||
                id: 'navigateToItem',
 | 
			
		||||
                cssClass: this.embed.cssClass,
 | 
			
		||||
                name: 'Navigate to Item',
 | 
			
		||||
                description: 'Navigate to the item with the current time settings.',
 | 
			
		||||
                onItemClicked: () => this.navigateToItem()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const navigateToItemInTime = {
 | 
			
		||||
                id: 'navigateToItemInTime',
 | 
			
		||||
                cssClass: this.embed.cssClass,
 | 
			
		||||
                name: 'Navigate to Item in Time',
 | 
			
		||||
                description: 'Navigate to the item in its time frame when captured.',
 | 
			
		||||
                onItemClicked: () => this.navigateToItemInTime()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            const quickView = {
 | 
			
		||||
                id: 'quickView',
 | 
			
		||||
                cssClass: 'icon-eye-open',
 | 
			
		||||
                name: 'Quick View',
 | 
			
		||||
                description: 'Full screen overlay view of the item.',
 | 
			
		||||
                onItemClicked: () => this.previewEmbed()
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.menuActions = this.menuActions.concat([quickView, navigateToItem, navigateToItemInTime]);
 | 
			
		||||
 | 
			
		||||
            if (!this.isLocked) {
 | 
			
		||||
                const removeEmbed = {
 | 
			
		||||
                    id: 'removeEmbed',
 | 
			
		||||
                    cssClass: 'icon-trash',
 | 
			
		||||
                    name: this.removeActionString,
 | 
			
		||||
                    description: 'Permanently delete this embed from this Notebook entry.',
 | 
			
		||||
                    onItemClicked: this.getRemoveDialog.bind(this)
 | 
			
		||||
                };
 | 
			
		||||
 | 
			
		||||
                this.menuActions.push(removeEmbed);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
        async setEmbedObjectPath() {
 | 
			
		||||
            this.objectPath = await this.openmct.objects.getOriginalPath(this.embed.domainObject.identifier);
 | 
			
		||||
 | 
			
		||||
            if (this.objectPath.length > 0 && this.objectPath[this.objectPath.length - 1].type === 'root') {
 | 
			
		||||
                this.objectPath.pop();
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        annotateSnapshot() {
 | 
			
		||||
            const annotateVue = new Vue({
 | 
			
		||||
@@ -179,7 +228,11 @@ export default {
 | 
			
		||||
                    painterroInstance.show(object.configuration.fullSizeImageURL);
 | 
			
		||||
                });
 | 
			
		||||
        },
 | 
			
		||||
        changeLocation() {
 | 
			
		||||
        navigateToItem() {
 | 
			
		||||
            const url = objectPathToUrl(this.openmct, this.objectPath);
 | 
			
		||||
            this.openmct.router.navigate(url);
 | 
			
		||||
        },
 | 
			
		||||
        navigateToItemInTime() {
 | 
			
		||||
            const hash = this.embed.historicLink;
 | 
			
		||||
 | 
			
		||||
            const bounds = this.openmct.time.bounds();
 | 
			
		||||
 
 | 
			
		||||
@@ -31,15 +31,28 @@
 | 
			
		||||
    @click="selectEntry($event, entry)"
 | 
			
		||||
>
 | 
			
		||||
    <div class="c-ne__time-and-content">
 | 
			
		||||
        <div class="c-ne__time-and-creator">
 | 
			
		||||
            <span class="c-ne__created-date">{{ createdOnDate }}</span>
 | 
			
		||||
            <span class="c-ne__created-time">{{ createdOnTime }}</span>
 | 
			
		||||
 | 
			
		||||
        <div class="c-ne__time-and-creator-and-delete">
 | 
			
		||||
            <div class="c-ne__time-and-creator">
 | 
			
		||||
                <span class="c-ne__created-date">{{ createdOnDate }}</span>
 | 
			
		||||
                <span class="c-ne__created-time">{{ createdOnTime }}</span>
 | 
			
		||||
                <span
 | 
			
		||||
                    v-if="entry.createdBy"
 | 
			
		||||
                    class="c-ne__creator"
 | 
			
		||||
                >
 | 
			
		||||
                    <span class="icon-person"></span> {{ entry.createdBy }}
 | 
			
		||||
                </span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <span
 | 
			
		||||
                v-if="entry.createdBy"
 | 
			
		||||
                class="c-ne__creator"
 | 
			
		||||
                v-if="!readOnly && !isLocked"
 | 
			
		||||
                class="c-ne__local-controls--hidden"
 | 
			
		||||
            >
 | 
			
		||||
                <span class="icon-person"></span> {{ entry.createdBy }}
 | 
			
		||||
                <button
 | 
			
		||||
                    class="c-ne__remove c-icon-button c-icon-button--major icon-trash"
 | 
			
		||||
                    title="Delete this entry"
 | 
			
		||||
                    tabindex="-1"
 | 
			
		||||
                    @click="deleteEntry"
 | 
			
		||||
                >
 | 
			
		||||
                </button>
 | 
			
		||||
            </span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="c-ne__content">
 | 
			
		||||
@@ -94,30 +107,26 @@
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="c-snapshots c-ne__embeds">
 | 
			
		||||
                <NotebookEmbed
 | 
			
		||||
                    v-for="embed in entry.embeds"
 | 
			
		||||
                    :key="embed.id"
 | 
			
		||||
                    :embed="embed"
 | 
			
		||||
                    :is-locked="isLocked"
 | 
			
		||||
                    @removeEmbed="removeEmbed"
 | 
			
		||||
                    @updateEmbed="updateEmbed"
 | 
			
		||||
                />
 | 
			
		||||
            <div
 | 
			
		||||
                :class="{'c-scrollcontainer': enableEmbedsWrapperScroll }"
 | 
			
		||||
            >
 | 
			
		||||
                <div
 | 
			
		||||
                    ref="embedsWrapper"
 | 
			
		||||
                    class="c-snapshots c-ne__embeds-wrapper"
 | 
			
		||||
                >
 | 
			
		||||
                    <NotebookEmbed
 | 
			
		||||
                        v-for="embed in entry.embeds"
 | 
			
		||||
                        ref="embeds"
 | 
			
		||||
                        :key="embed.id"
 | 
			
		||||
                        :embed="embed"
 | 
			
		||||
                        :is-locked="isLocked"
 | 
			
		||||
                        @removeEmbed="removeEmbed"
 | 
			
		||||
                        @updateEmbed="updateEmbed"
 | 
			
		||||
                    />
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div
 | 
			
		||||
        v-if="!readOnly && !isLocked"
 | 
			
		||||
        class="c-ne__local-controls--hidden"
 | 
			
		||||
    >
 | 
			
		||||
        <button
 | 
			
		||||
            class="c-icon-button c-icon-button--major icon-trash"
 | 
			
		||||
            title="Delete this entry"
 | 
			
		||||
            tabindex="-1"
 | 
			
		||||
            @click="deleteEntry"
 | 
			
		||||
        >
 | 
			
		||||
        </button>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div
 | 
			
		||||
        v-if="readOnly"
 | 
			
		||||
        class="c-ne__section-and-page"
 | 
			
		||||
@@ -147,6 +156,8 @@ import TextHighlight from '../../../utils/textHighlight/TextHighlight.vue';
 | 
			
		||||
import { createNewEmbed } from '../utils/notebook-entries';
 | 
			
		||||
import { saveNotebookImageDomainObject, updateNamespaceOfDomainObject } from '../utils/notebook-image';
 | 
			
		||||
 | 
			
		||||
import _ from 'lodash';
 | 
			
		||||
 | 
			
		||||
import Moment from 'moment';
 | 
			
		||||
 | 
			
		||||
const UNKNOWN_USER = 'Unknown';
 | 
			
		||||
@@ -211,6 +222,11 @@ export default {
 | 
			
		||||
            required: true
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
        return {
 | 
			
		||||
            enableEmbedsWrapperScroll: false
 | 
			
		||||
        };
 | 
			
		||||
    },
 | 
			
		||||
    computed: {
 | 
			
		||||
        createdOnDate() {
 | 
			
		||||
            return this.formatTime(this.entry.createdOn, 'YYYY-MM-DD');
 | 
			
		||||
@@ -246,8 +262,21 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    mounted() {
 | 
			
		||||
        this.manageEmbedLayout = _.debounce(this.manageEmbedLayout, 400);
 | 
			
		||||
 | 
			
		||||
        if (this.$refs.embedsWrapper) {
 | 
			
		||||
            this.embedsWrapperResizeObserver = new ResizeObserver(this.manageEmbedLayout);
 | 
			
		||||
            this.embedsWrapperResizeObserver.observe(this.$refs.embedsWrapper);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.manageEmbedLayout();
 | 
			
		||||
        this.dropOnEntry = this.dropOnEntry.bind(this);
 | 
			
		||||
    },
 | 
			
		||||
    beforeDestroy() {
 | 
			
		||||
        if (this.embedsWrapperResizeObserver) {
 | 
			
		||||
            this.embedsWrapperResizeObserver.unobserve(this.$refs.embedsWrapper);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    methods: {
 | 
			
		||||
        async addNewEmbed(objectPath) {
 | 
			
		||||
            const bounds = this.openmct.time.bounds();
 | 
			
		||||
@@ -259,6 +288,8 @@ export default {
 | 
			
		||||
            };
 | 
			
		||||
            const newEmbed = await createNewEmbed(snapshotMeta);
 | 
			
		||||
            this.entry.embeds.push(newEmbed);
 | 
			
		||||
 | 
			
		||||
            this.manageEmbedLayout();
 | 
			
		||||
        },
 | 
			
		||||
        cancelEditMode(event) {
 | 
			
		||||
            const isEditing = this.openmct.editor.isEditing();
 | 
			
		||||
@@ -279,6 +310,17 @@ export default {
 | 
			
		||||
        deleteEntry() {
 | 
			
		||||
            this.$emit('deleteEntry', this.entry.id);
 | 
			
		||||
        },
 | 
			
		||||
        manageEmbedLayout() {
 | 
			
		||||
            if (this.$refs.embeds) {
 | 
			
		||||
                const embedsWrapperLength = this.$refs.embedsWrapper.clientWidth;
 | 
			
		||||
                const embedsTotalWidth = this.$refs.embeds.reduce((total, embed) => {
 | 
			
		||||
                    return embed.$el.clientWidth + total;
 | 
			
		||||
                }, 0);
 | 
			
		||||
 | 
			
		||||
                this.enableEmbedsWrapperScroll = embedsTotalWidth > embedsWrapperLength;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        },
 | 
			
		||||
        async dropOnEntry($event) {
 | 
			
		||||
            $event.stopImmediatePropagation();
 | 
			
		||||
 | 
			
		||||
@@ -336,6 +378,8 @@ export default {
 | 
			
		||||
            this.entry.embeds.splice(embedPosition, 1);
 | 
			
		||||
 | 
			
		||||
            this.timestampAndUpdate();
 | 
			
		||||
 | 
			
		||||
            this.manageEmbedLayout();
 | 
			
		||||
        },
 | 
			
		||||
        updateEmbed(newEmbed) {
 | 
			
		||||
            this.entry.embeds.some(e => {
 | 
			
		||||
 
 | 
			
		||||
@@ -463,6 +463,8 @@ $transInBounceBig: all 300ms cubic-bezier(.2,1.6,.6,3);
 | 
			
		||||
$createBtnTextTransform: uppercase;
 | 
			
		||||
$colorDiscreteItemBg: rgba($colorBodyFg,0.1);
 | 
			
		||||
$colorDiscreteItemCurrentBg: rgba($colorOk,0.3);
 | 
			
		||||
$scrollContainer: $colorBodyBg;
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
@mixin discreteItem() {
 | 
			
		||||
    background: $colorDiscreteItemBg;
 | 
			
		||||
 
 | 
			
		||||
@@ -467,6 +467,7 @@ $transInBounceBig: all 300ms cubic-bezier(.2,1.6,.6,3);
 | 
			
		||||
$createBtnTextTransform: uppercase;
 | 
			
		||||
$colorDiscreteItemBg: rgba($colorBodyFg,0.1);
 | 
			
		||||
$colorDiscreteItemCurrentBg: rgba($colorOk,0.3);
 | 
			
		||||
$scrollContainer: $colorBodyBg;
 | 
			
		||||
 | 
			
		||||
@mixin discreteItem() {
 | 
			
		||||
    background: rgba($colorBodyFg,0.1);
 | 
			
		||||
 
 | 
			
		||||
@@ -463,6 +463,7 @@ $transInBounceBig: all 300ms cubic-bezier(.2,1.6,.6,3);
 | 
			
		||||
$createBtnTextTransform: uppercase;
 | 
			
		||||
$colorDiscreteItemBg: rgba($colorBodyFg,0.1);
 | 
			
		||||
$colorDiscreteItemCurrentBg: rgba($colorOk,0.3);
 | 
			
		||||
$scrollContainer: rgba(102, 102, 102, 0.1);
 | 
			
		||||
 | 
			
		||||
@mixin discreteItem() {
 | 
			
		||||
    background: $colorDiscreteItemBg;
 | 
			
		||||
 
 | 
			
		||||
@@ -327,3 +327,6 @@ $bg-icon-timelist: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://ww
 | 
			
		||||
$bg-icon-plot-scatter: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cg data-name='Layer 2'%3e%3cpath d='M96 0C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96ZM64 176a48 48 0 1 1 48 48 48 48 0 0 1-48-48Zm80 240a48 48 0 1 1 48-48 48 48 0 0 1-48 48Zm128-96a48 48 0 1 1 48-48 48 48 0 0 1-48 48Zm0-160a48 48 0 1 1 48-48 48 48 0 0 1-48 48Zm128 256a48 48 0 1 1 48-48 48 48 0 0 1-48 48Z' data-name='Layer 1'/%3e%3c/g%3e%3c/svg%3e");
 | 
			
		||||
$bg-icon-notebook-shift-log: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M448 55.36c0-39.95-27.69-63.66-61.54-52.68L0 128h448V55.36ZM448 160H0v288c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64ZM128 416H64v-64h64v64Zm0-96H64v-64h64v64Zm320 96H192v-64h256v64Zm0-96H192v-64h256v64Z'/%3e%3c/svg%3e");
 | 
			
		||||
$bg-icon-telemetry-aggregate: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cg data-name='Layer 2'%3e%3cg data-name='Layer 3'%3e%3cpath d='M39 197.72c7-20.72 18.74-50.4 34.6-74.18C92.91 94.65 114.79 80 138.67 80s45.75 14.65 65 43.54c15.86 23.78 27.57 53.46 34.6 74.18 15.44 45.48 31.56 67.49 39 73.27 7.47-5.78 23.6-27.79 39-73.27 7-20.72 18.74-50.4 34.61-74.18q13.9-20.85 29.56-31.75A207.78 207.78 0 0 0 208 0C93.12 0 0 93.12 0 208a208.14 208.14 0 0 0 7.39 55.09c8.39-10.87 20.2-31.67 31.61-65.37Z'/%3e%3cpath d='M377 218.28c-7 20.72-18.74 50.4-34.6 74.18-19.28 28.89-41.16 43.54-65 43.54s-45.75-14.65-65-43.54c-15.86-23.78-27.57-53.46-34.6-74.18-15.44-45.48-31.57-67.49-39-73.27-7.47 5.78-23.6 27.79-39 73.27-7.19 20.72-18.9 50.4-34.8 74.18q-13.9 20.85-29.56 31.75A207.78 207.78 0 0 0 208 416c114.88 0 208-93.12 208-208a208.14 208.14 0 0 0-7.39-55.09c-8.39 10.87-20.2 31.67-31.61 65.37Z'/%3e%3cpath d='M460.78 167.31A258.4 258.4 0 0 1 464 208a255.84 255.84 0 0 1-256 256 258.4 258.4 0 0 1-40.69-3.22A207.23 207.23 0 0 0 304 512c114.88 0 208-93.12 208-208a207.23 207.23 0 0 0-51.22-136.69Z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e");
 | 
			
		||||
$bg-icon-trash: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='512px' height='512px' viewBox='0 0 512 512' enable-background='new 0 0 512 512' xml:space='preserve'%3e%3cpath d='M416,64h-96.18V32c0-17.6-14.4-32-32-32h-64c-17.6,0-32,14.4-32,32v32H96c-52.8,0-96,36-96,80s0,80,0,80h32v192 c0,52.8,43.2,96,96,96h256c52.8,0,96-43.2,96-96V224h32c0,0,0-36,0-80S468.8,64,416,64z M160,416H96V224h64V416z M288,416h-64V224 h64V416z M416,416h-64V224h64V416z'/%3e%3c/svg%3e");
 | 
			
		||||
$bg-icon-eye-open: url("data:image/svg+xml;charset=UTF-8,%3csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 512 512' style='enable-background:new 0 0 512 512;' xml:space='preserve'%3e%3cstyle type='text/css'%3e .st0%7bfill:%2300A14B;%7d %3c/style%3e%3ctitle%3eicon-eye-open-v2%3c/title%3e%3cg%3e%3cpath class='st0' d='M256,58.2c-122.9,0-226.1,84-255.4,197.8C29.9,369.7,133.1,453.8,256,453.8s226.1-84,255.4-197.8 C482.1,142.3,378.9,58.2,256,58.2z M414.6,294.2c-11.3,17.2-25.3,32.4-41.5,45.2c-16.4,12.9-34.5,22.8-54,29.7 c-20.2,7.1-41.4,10.7-63,10.7s-42.9-3.6-63-10.7c-19.5-6.9-37.7-16.9-54-29.7c-16.2-12.8-30.2-27.9-41.5-45.2 c-7.9-12-14.4-24.8-19.3-38.2c5-13.4,11.5-26.2,19.3-38.2c11.3-17.2,25.3-32.4,41.5-45.2c16.4-12.9,34.5-22.8,54-29.7 c20.2-7.1,41.4-10.7,63-10.7s42.9,3.6,63,10.7c19.5,6.9,37.7,16.9,54,29.7c16.2,12.8,30.2,27.9,41.5,45.2 c7.9,12,14.4,24.8,19.3,38.2C429,269.4,422.5,282.2,414.6,294.2z'/%3e%3ccircle class='st0' cx='256' cy='256' r='96'/%3e%3c/g%3e%3c/svg%3e");
 | 
			
		||||
$bg-icon-camera: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3ctitle%3eicon-camera-v2%3c/title%3e%3cpath d='M448,128H384L320,0H192L128,128H64A64.2,64.2,0,0,0,0,192V448a64.2,64.2,0,0,0,64,64H448a64.2,64.2,0,0,0,64-64V192A64.2,64.2,0,0,0,448,128ZM256,432A128,128,0,1,1,384,304,128,128,0,0,1,256,432Z'/%3e%3c/svg%3e");
 | 
			
		||||
 
 | 
			
		||||
@@ -462,6 +462,15 @@ input[type=number].c-input-number--no-spinners {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-scrollcontainer{
 | 
			
		||||
    @include nice-input();
 | 
			
		||||
    margin-top: $interiorMargin;
 | 
			
		||||
    background: $scrollContainer;
 | 
			
		||||
    border-radius: $controlCr;
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
    padding: $interiorMarginSm;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SELECTS
 | 
			
		||||
select {
 | 
			
		||||
    @include appearanceNone();
 | 
			
		||||
 
 | 
			
		||||
@@ -265,3 +265,6 @@
 | 
			
		||||
.bg-icon-plot-scatter { @include glyphBg($bg-icon-plot-scatter); }
 | 
			
		||||
.bg-icon-notebook-shift-log { @include glyphBg($bg-icon-notebook-shift-log); }
 | 
			
		||||
.bg-icon-telemetry-aggregate { @include glyphBg($bg-icon-telemetry-aggregate); }
 | 
			
		||||
.bg-icon-trash { @include glyphBg($bg-icon-trash); }
 | 
			
		||||
.bg-icon-eye-open { @include glyphBg($bg-icon-eye-open); }
 | 
			
		||||
.bg-icon-camera { @include glyphBg($bg-icon-camera); }
 | 
			
		||||
 
 | 
			
		||||
@@ -303,11 +303,25 @@
 | 
			
		||||
        opacity: 0.7;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__time-and-creator,
 | 
			
		||||
    &__time-and-creator-and-delete,
 | 
			
		||||
    &__input {
 | 
			
		||||
        padding: $p;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__input{
 | 
			
		||||
        word-break: break-word;
 | 
			
		||||
    }
 | 
			
		||||
    &__time-and-creator-and-delete{
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        > * + *{
 | 
			
		||||
            float: right;
 | 
			
		||||
            margin-left: auto;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__creator [class*='icon'] {
 | 
			
		||||
        font-size: 0.95em;
 | 
			
		||||
    }
 | 
			
		||||
@@ -315,6 +329,7 @@
 | 
			
		||||
    &__time-and-content {
 | 
			
		||||
        display: block;
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        overflow: visible;
 | 
			
		||||
 | 
			
		||||
        > * + * {
 | 
			
		||||
            margin-top: $interiorMarginSm;
 | 
			
		||||
@@ -332,9 +347,10 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__content {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        margin-right: $interiorMarginSm;
 | 
			
		||||
        margin-top: $interiorMargin;
 | 
			
		||||
 | 
			
		||||
        > [class*="__"] + [class*="__"] {
 | 
			
		||||
            margin-top: $interiorMarginSm;
 | 
			
		||||
@@ -358,7 +374,8 @@
 | 
			
		||||
        @include inlineInput;
 | 
			
		||||
        padding-left: $p;
 | 
			
		||||
        padding-right: $p;
 | 
			
		||||
 | 
			
		||||
        overflow: unset;
 | 
			
		||||
        margin-bottom: $interiorMargin;
 | 
			
		||||
        @include hover {
 | 
			
		||||
            &:not(:focus, .locked) {
 | 
			
		||||
                background: rgba($colorBodyFg, 0.1);
 | 
			
		||||
@@ -394,12 +411,17 @@
 | 
			
		||||
            opacity: 0.7;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__remove{
 | 
			
		||||
        float: right;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/****************************** EMBEDS */
 | 
			
		||||
@mixin snapThumb() {
 | 
			
		||||
    // LEGACY: TODO: refactor when .snap-thumb in New Entry dialog is refactored
 | 
			
		||||
    $d: 30px;
 | 
			
		||||
    $d: 40px;
 | 
			
		||||
    border: 1px solid $colorInteriorBorder;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    width: $d;
 | 
			
		||||
@@ -417,21 +439,24 @@
 | 
			
		||||
    // LEGACY,
 | 
			
		||||
    @include snapThumb();
 | 
			
		||||
}
 | 
			
		||||
.c-ne__embeds-wrapper{
 | 
			
		||||
    max-height: 75px;
 | 
			
		||||
    padding-left: $interiorMargin;
 | 
			
		||||
    padding-top: $interiorMargin;
 | 
			
		||||
    display: flex;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-ne__embed {
 | 
			
		||||
    @include discreteItemInnerElem();
 | 
			
		||||
    display: inline-flex;
 | 
			
		||||
    flex: 0 0 auto;
 | 
			
		||||
    padding: $interiorMargin;
 | 
			
		||||
 | 
			
		||||
    [class*="__"] + [class*="__"] {
 | 
			
		||||
        margin-left: $interiorMargin;
 | 
			
		||||
    }
 | 
			
		||||
    border: 1px solid $colorInteriorBorder;
 | 
			
		||||
 | 
			
		||||
    &__info {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        flex-direction: column;
 | 
			
		||||
 | 
			
		||||
        margin-left: $interiorMargin;
 | 
			
		||||
        a {
 | 
			
		||||
            color: $colorKey;
 | 
			
		||||
        }
 | 
			
		||||
@@ -445,9 +470,10 @@
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &__link {
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        &:before {
 | 
			
		||||
            display: block;
 | 
			
		||||
            font-size: 0.85em;
 | 
			
		||||
            font-size: 1em;
 | 
			
		||||
            margin-right: $interiorMarginSm;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -460,6 +486,24 @@
 | 
			
		||||
    &__snap-thumb {
 | 
			
		||||
        @include snapThumb();
 | 
			
		||||
    }
 | 
			
		||||
    &__actions{
 | 
			
		||||
        margin: $interiorMarginSm;
 | 
			
		||||
    }
 | 
			
		||||
    &__actions-menu {
 | 
			
		||||
        width: 55vh;
 | 
			
		||||
        max-width: 500px; 
 | 
			
		||||
        height: 130px;
 | 
			
		||||
        z-index: 70;
 | 
			
		||||
        [class*="__icon"] {
 | 
			
		||||
            filter: $colorKeyFilter;
 | 
			
		||||
            margin: 0%;
 | 
			
		||||
            height: 4vh;
 | 
			
		||||
        }
 | 
			
		||||
        [class*="__item-description"] {
 | 
			
		||||
            min-width: 200px;         
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/****************************** SNAPSHOTTING */
 | 
			
		||||
@@ -700,6 +744,7 @@ body.mobile {
 | 
			
		||||
    .c-notebook__entry {
 | 
			
		||||
        [class*="local-controls"] {
 | 
			
		||||
            display: none;
 | 
			
		||||
            height: fit-content;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@
 | 
			
		||||
        title="Add new tag"
 | 
			
		||||
        @click="addTag"
 | 
			
		||||
    >
 | 
			
		||||
        <div class="c-icon-button__label">Add Tag</div>
 | 
			
		||||
        <div class="c-icon-button__label c-tag-btn__label">Add Tag</div>
 | 
			
		||||
    </button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 
 | 
			
		||||
@@ -54,6 +54,10 @@
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.c-tag-btn__label {
 | 
			
		||||
  overflow: visible!important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************* HOVERS */
 | 
			
		||||
.has-tag-applier {
 | 
			
		||||
  // Apply this class to all components that should trigger tag removal btn on hover
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user