mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 02:29:24 +00:00
Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
044a4c5bae | |||
a6c841b46c | |||
9cffe376cd | |||
ad929ce411 | |||
98e61ad43a | |||
f30d56be21 | |||
2bc327db95 | |||
ec8117fc8b | |||
dd94251ca7 | |||
961aa028bf | |||
1922269f0e | |||
3ff1576cbb | |||
5c67414f4e | |||
f162573874 | |||
1084c360a7 | |||
9f25eb68d9 | |||
b215f00c03 | |||
5a1c329c66 | |||
00a5cbd2fd | |||
a2d698d5c1 | |||
5685a5b393 | |||
164f39695e | |||
c384cf67da | |||
417b225505 | |||
e5e93f311c | |||
39e6d9c90c | |||
60d021ef82 | |||
59880955a2 | |||
b51ed7e844 | |||
7bbaec4006 | |||
c0f24b3925 | |||
4e79725897 | |||
0674c9fc33 | |||
de1b877954 | |||
4db2f547d9 |
@ -40,9 +40,6 @@ test.describe('Move item tests', () => {
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').click();
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folder1);
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
@ -59,9 +56,6 @@ test.describe('Move item tests', () => {
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').click();
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(folder2);
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
@ -97,9 +91,6 @@ test.describe('Move item tests', () => {
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').click();
|
||||
await page.locator('text=Properties Title Notes >> input[type="text"]').fill(telemetryTable);
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await page.locator('text=OK').click();
|
||||
|
||||
// Finish editing and save Telemetry Table
|
||||
|
@ -28,9 +28,7 @@ const { test } = require('../../fixtures.js');
|
||||
const { expect } = require('@playwright/test');
|
||||
const path = require('path');
|
||||
|
||||
// https://github.com/nasa/openmct/issues/4323#issuecomment-1067282651
|
||||
|
||||
test.describe('Persistence operations', () => {
|
||||
test.describe('Persistence operations @addInit', () => {
|
||||
// add non persistable root item
|
||||
test.beforeEach(async ({ page }) => {
|
||||
// eslint-disable-next-line no-undef
|
||||
@ -38,6 +36,10 @@ test.describe('Persistence operations', () => {
|
||||
});
|
||||
|
||||
test('Persistability should be respected in the create form location field', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/4323'
|
||||
});
|
||||
// Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
|
30
e2e/tests/plugins/gauge/addInitGauge.js
Normal file
30
e2e/tests/plugins/gauge/addInitGauge.js
Normal file
@ -0,0 +1,30 @@
|
||||
/*****************************************************************************
|
||||
* 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 will be called from the test suite with
|
||||
// await page.addInitScript({ path: path.join(__dirname, 'addInitGauge.js') });
|
||||
// it will install the Gauge since it is not installed by default
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const openmct = window.openmct;
|
||||
openmct.install(openmct.plugins.Gauge());
|
||||
});
|
@ -41,9 +41,6 @@ test.describe('Example Imagery', () => {
|
||||
// Click text=Example Imagery
|
||||
await page.click('text=Example Imagery');
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
// Click text=OK
|
||||
await Promise.all([
|
||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||
@ -331,38 +328,12 @@ test('Example Imagery in Display layout', async ({ page }) => {
|
||||
|
||||
return newImageCount;
|
||||
}, {
|
||||
message: "verify that new images still stream in",
|
||||
message: "verify that old images are discarded",
|
||||
timeout: 6 * 1000
|
||||
}).toBeGreaterThan(imageCount);
|
||||
}).toBe(imageCount);
|
||||
|
||||
// Verify selected image is still displayed
|
||||
await expect(selectedImage).toBeVisible();
|
||||
|
||||
// Unpause imagery
|
||||
await page.locator('.pause-play').click();
|
||||
|
||||
//Get background-image url from background-image css prop
|
||||
const backgroundImage = page.locator('.c-imagery__main-image__background-image');
|
||||
let backgroundImageUrl = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
let backgroundImageUrl1 = backgroundImageUrl.slice(1, -1); //forgive me, padre
|
||||
console.log('backgroundImageUrl1 ' + backgroundImageUrl1);
|
||||
|
||||
let backgroundImageUrl2;
|
||||
await expect.poll(async () => {
|
||||
// Verify next image has updated
|
||||
let backgroundImageUrlNext = await backgroundImage.evaluate((el) => {
|
||||
return window.getComputedStyle(el).getPropertyValue('background-image').match(/url\(([^)]+)\)/)[1];
|
||||
});
|
||||
backgroundImageUrl2 = backgroundImageUrlNext.slice(1, -1); //forgive me, padre
|
||||
|
||||
return backgroundImageUrl2;
|
||||
}, {
|
||||
message: "verify next image has updated",
|
||||
timeout: 6 * 1000
|
||||
}).not.toBe(backgroundImageUrl1);
|
||||
console.log('backgroundImageUrl2 ' + backgroundImageUrl2);
|
||||
});
|
||||
|
||||
test.describe('Example imagery thumbnails resize in display layouts', () => {
|
||||
|
@ -125,17 +125,17 @@ async function openContextMenuRestrictedNotebook(page) {
|
||||
return;
|
||||
}
|
||||
|
||||
test.describe('Restricted Notebook', () => {
|
||||
test.describe('Restricted Notebook @addInit', () => {
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await startAndAddNotebookObject(page);
|
||||
});
|
||||
|
||||
test('Can be renamed', async ({ page }) => {
|
||||
test('Can be renamed @addInit', async ({ page }) => {
|
||||
await expect.soft(page.locator('.l-browse-bar__object-name')).toContainText(`Unnamed ${CUSTOM_NAME}`);
|
||||
});
|
||||
|
||||
test('Can be deleted if there are no locked pages', async ({ page }) => {
|
||||
test('Can be deleted if there are no locked pages @addInit', async ({ page }) => {
|
||||
await openContextMenuRestrictedNotebook(page);
|
||||
|
||||
const menuOptions = page.locator('.c-menu ul');
|
||||
@ -158,7 +158,7 @@ test.describe('Restricted Notebook', () => {
|
||||
expect.soft(await restrictedNotebookTreeObject.count()).toEqual(0);
|
||||
});
|
||||
|
||||
test('Can be locked if at least one page has one entry', async ({ page }) => {
|
||||
test('Can be locked if at least one page has one entry @addInit', async ({ page }) => {
|
||||
|
||||
await enterTextEntry(page);
|
||||
|
||||
@ -168,7 +168,7 @@ test.describe('Restricted Notebook', () => {
|
||||
|
||||
});
|
||||
|
||||
test.describe('Restricted Notebook with at least one entry and with the page locked', () => {
|
||||
test.describe('Restricted Notebook with at least one entry and with the page locked @addInit', () => {
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await startAndAddNotebookObject(page);
|
||||
@ -179,7 +179,7 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
||||
await page.locator('button.c-notebook__toggle-nav-button').click();
|
||||
});
|
||||
|
||||
test('Locked page should now be in a locked state', async ({ page }) => {
|
||||
test('Locked page should now be in a locked state @addInit', async ({ page }) => {
|
||||
// main lock message on page
|
||||
const lockMessage = page.locator('text=This page has been committed and cannot be modified or removed');
|
||||
expect.soft(await lockMessage.count()).toEqual(1);
|
||||
@ -197,7 +197,7 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
||||
|
||||
});
|
||||
|
||||
test('Can still: add page, rename, add entry, delete unlocked pages', async ({ page }) => {
|
||||
test('Can still: add page, rename, add entry, delete unlocked pages @addInit', async ({ page }) => {
|
||||
// Click text=Page Add >> button
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
@ -237,14 +237,14 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('Restricted Notebook with a page locked and with an embed', () => {
|
||||
test.describe('Restricted Notebook with a page locked and with an embed @addInit', () => {
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await startAndAddNotebookObject(page);
|
||||
await dragAndDropEmbed(page);
|
||||
});
|
||||
|
||||
test('Allows embeds to be deleted if page unlocked', async ({ page }) => {
|
||||
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
|
||||
|
||||
@ -252,7 +252,7 @@ test.describe('Restricted Notebook with a page locked and with an embed', () =>
|
||||
await expect.soft(embedMenu).toContainText('Remove This Embed');
|
||||
});
|
||||
|
||||
test('Disallows embeds to be deleted if page locked', async ({ page }) => {
|
||||
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
|
||||
|
@ -39,9 +39,6 @@ test.describe('Telemetry Table', () => {
|
||||
await page.locator(createButton).click();
|
||||
await page.locator('li:has-text("Telemetry Table")').click();
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
@ -59,9 +56,6 @@ test.describe('Telemetry Table', () => {
|
||||
// add Sine Wave Generator with defaults
|
||||
await page.locator('li:has-text("Sine Wave Generator")').click();
|
||||
|
||||
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
|
||||
await page.click('form[name="mctForm"] a:has-text("My Items")');
|
||||
|
||||
await Promise.all([
|
||||
page.waitForNavigation(),
|
||||
page.locator('text=OK').click(),
|
||||
|
184
e2e/tests/plugins/timer/timer.e2e.spec.js
Normal file
184
e2e/tests/plugins/timer/timer.e2e.spec.js
Normal file
@ -0,0 +1,184 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
const { test } = require('../../../fixtures.js');
|
||||
const { expect } = require('@playwright/test');
|
||||
|
||||
test.describe('Timer', () => {
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
//Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
|
||||
// Click 'Timer'
|
||||
await page.click('text=Timer');
|
||||
|
||||
// Click text=OK
|
||||
await Promise.all([
|
||||
page.waitForNavigation({waitUntil: 'networkidle'}),
|
||||
page.click('text=OK')
|
||||
]);
|
||||
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Timer');
|
||||
});
|
||||
|
||||
test('Can perform actions on the Timer', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/4313'
|
||||
});
|
||||
|
||||
await test.step("From the tree context menu", async () => {
|
||||
await triggerTimerContextMenuAction(page, 'Start');
|
||||
await triggerTimerContextMenuAction(page, 'Pause');
|
||||
await triggerTimerContextMenuAction(page, 'Restart at 0');
|
||||
await triggerTimerContextMenuAction(page, 'Stop');
|
||||
});
|
||||
|
||||
await test.step("From the 3dot menu", async () => {
|
||||
await triggerTimer3dotMenuAction(page, 'Start');
|
||||
await triggerTimer3dotMenuAction(page, 'Pause');
|
||||
await triggerTimer3dotMenuAction(page, 'Restart at 0');
|
||||
await triggerTimer3dotMenuAction(page, 'Stop');
|
||||
});
|
||||
|
||||
await test.step("From the object view", async () => {
|
||||
await triggerTimerViewAction(page, 'Start');
|
||||
await triggerTimerViewAction(page, 'Pause');
|
||||
await triggerTimerViewAction(page, 'Restart at 0');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Actions that can be performed on a timer from context menus.
|
||||
* @typedef {'Start' | 'Stop' | 'Pause' | 'Restart at 0'} TimerAction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Actions that can be performed on a timer from the object view.
|
||||
* @typedef {'Start' | 'Pause' | 'Restart at 0'} TimerViewAction
|
||||
*/
|
||||
|
||||
/**
|
||||
* Open the timer context menu from the object tree.
|
||||
* Expands the 'My Items' folder if it is not already expanded.
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function openTimerContextMenu(page) {
|
||||
const myItemsFolder = page.locator('text=Open MCT My Items >> span').nth(3);
|
||||
const className = await myItemsFolder.getAttribute('class');
|
||||
if (!className.includes('c-disclosure-triangle--expanded')) {
|
||||
await myItemsFolder.click();
|
||||
}
|
||||
|
||||
await page.locator(`a:has-text("Unnamed Timer")`).click({
|
||||
button: 'right'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a timer action from the tree context menu
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {TimerAction} action
|
||||
*/
|
||||
async function triggerTimerContextMenuAction(page, action) {
|
||||
const menuAction = `.c-menu ul li >> text="${action}"`;
|
||||
await openTimerContextMenu(page);
|
||||
await page.locator(menuAction).click();
|
||||
assertTimerStateAfterAction(page, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a timer action from the 3dot menu
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {TimerAction} action
|
||||
*/
|
||||
async function triggerTimer3dotMenuAction(page, action) {
|
||||
const menuAction = `.c-menu ul li >> text="${action}"`;
|
||||
const threeDotMenuButton = 'button[title="More options"]';
|
||||
let isActionAvailable = false;
|
||||
let iterations = 0;
|
||||
// Dismiss/open the 3dot menu until the action is available
|
||||
// or a maxiumum number of iterations is reached
|
||||
while (!isActionAvailable && iterations <= 20) {
|
||||
await page.click('.c-object-view');
|
||||
await page.click(threeDotMenuButton);
|
||||
isActionAvailable = await page.locator(menuAction).isVisible();
|
||||
iterations++;
|
||||
}
|
||||
|
||||
await page.locator(menuAction).click();
|
||||
assertTimerStateAfterAction(page, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a timer action from the object view
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {TimerViewAction} action
|
||||
*/
|
||||
async function triggerTimerViewAction(page, action) {
|
||||
const buttonTitle = buttonTitleFromAction(action);
|
||||
await page.click(`button[title="${buttonTitle}"]`);
|
||||
assertTimerStateAfterAction(page, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a TimerViewAction and returns the button title
|
||||
* @param {TimerViewAction} action
|
||||
*/
|
||||
function buttonTitleFromAction(action) {
|
||||
switch (action) {
|
||||
case 'Start':
|
||||
return 'Start';
|
||||
case 'Pause':
|
||||
return 'Pause';
|
||||
case 'Restart at 0':
|
||||
return 'Reset';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify the timer state after a timer action has been performed.
|
||||
* @param {import('@playwright/test').Page} page
|
||||
* @param {TimerAction} action
|
||||
*/
|
||||
async function assertTimerStateAfterAction(page, action) {
|
||||
let timerStateClass;
|
||||
switch (action) {
|
||||
case 'Start':
|
||||
case 'Restart at 0':
|
||||
timerStateClass = "is-started";
|
||||
break;
|
||||
case 'Stop':
|
||||
timerStateClass = 'is-stopped';
|
||||
break;
|
||||
case 'Pause':
|
||||
timerStateClass = 'is-paused';
|
||||
break;
|
||||
}
|
||||
|
||||
await expect.soft(page.locator('.c-timer')).toHaveClass(new RegExp(timerStateClass));
|
||||
}
|
72
e2e/tests/visual/addInit.visual.spec.js
Normal file
72
e2e/tests/visual/addInit.visual.spec.js
Normal file
@ -0,0 +1,72 @@
|
||||
/* eslint-disable no-undef */
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
Collection of Visual Tests set to run with modified init scripts to inject plugins not otherwise available in the default contexts.
|
||||
|
||||
These should only use functional expect statements to verify assumptions about the state
|
||||
in a test and not for functional verification of correctness. Visual tests are not supposed
|
||||
to "fail" on assertions. Instead, they should be used to detect changes between builds or branches.
|
||||
|
||||
Note: Larger testsuite sizes are OK due to the setup time associated with these tests.
|
||||
*/
|
||||
|
||||
const { test } = require('@playwright/test');
|
||||
const percySnapshot = require('@percy/playwright');
|
||||
const path = require('path');
|
||||
const sinon = require('sinon');
|
||||
|
||||
const VISUAL_GRACE_PERIOD = 5 * 1000; //Lets the application "simmer" before the snapshot is taken
|
||||
|
||||
// Snippet from https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
|
||||
// Will replace with cy.clock() equivalent
|
||||
test.beforeEach(async ({ context }) => {
|
||||
await context.addInitScript({
|
||||
path: path.join(__dirname, '../../..', './node_modules/sinon/pkg/sinon.js')
|
||||
});
|
||||
await context.addInitScript(() => {
|
||||
window.__clock = sinon.useFakeTimers({
|
||||
now: 0,
|
||||
shouldAdvanceTime: true
|
||||
}); //Set browser clock to UNIX Epoch
|
||||
});
|
||||
});
|
||||
|
||||
test('Visual - Default Gauge is correct @addInit', async ({ page }) => {
|
||||
|
||||
await page.addInitScript({ path: path.join(__dirname, '../plugins/gauge', './addInitGauge.js') });
|
||||
//Go to baseURL
|
||||
await page.goto('/', { waitUntil: 'networkidle' });
|
||||
|
||||
//Click the Create button
|
||||
await page.click('button:has-text("Create")');
|
||||
|
||||
await page.click('text=Gauge');
|
||||
|
||||
await page.click('text=OK');
|
||||
|
||||
// Take a snapshot of the newly created Gauge object
|
||||
await page.waitForTimeout(VISUAL_GRACE_PERIOD);
|
||||
await percySnapshot(page, 'Default Gauge');
|
||||
|
||||
});
|
@ -168,7 +168,7 @@ function getImageUrlListFromConfig(configuration) {
|
||||
}
|
||||
|
||||
function getImageLoadDelay(domainObject) {
|
||||
const imageLoadDelay = domainObject.configuration.imageLoadDelayInMilliSeconds;
|
||||
const imageLoadDelay = Math.trunc(Number(domainObject.configuration.imageLoadDelayInMilliSeconds));
|
||||
if (!imageLoadDelay) {
|
||||
openmctInstance.objects.mutate(domainObject, 'configuration.imageLoadDelayInMilliSeconds', DEFAULT_IMAGE_LOAD_DELAY_IN_MILISECONDS);
|
||||
|
||||
@ -190,7 +190,9 @@ function getRealtimeProvider() {
|
||||
subscribe: (domainObject, callback) => {
|
||||
const delay = getImageLoadDelay(domainObject);
|
||||
const interval = setInterval(() => {
|
||||
callback(pointForTimestamp(Date.now(), domainObject.name, getImageSamples(domainObject.configuration), delay));
|
||||
const imageSamples = getImageSamples(domainObject.configuration);
|
||||
const datum = pointForTimestamp(Date.now(), domainObject.name, imageSamples, delay);
|
||||
callback(datum);
|
||||
}, delay);
|
||||
|
||||
return () => {
|
||||
@ -229,8 +231,9 @@ function getLadProvider() {
|
||||
},
|
||||
request: (domainObject, options) => {
|
||||
const delay = getImageLoadDelay(domainObject);
|
||||
const datum = pointForTimestamp(Date.now(), domainObject.name, getImageSamples(domainObject.configuration), delay);
|
||||
|
||||
return Promise.resolve([pointForTimestamp(Date.now(), domainObject.name, delay)]);
|
||||
return Promise.resolve([datum]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openmct",
|
||||
"version": "2.0.5-SNAPSHOT",
|
||||
"version": "2.0.5",
|
||||
"description": "The Open MCT core platform",
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "7.18.2",
|
||||
|
@ -85,8 +85,6 @@ class ActionCollection extends EventEmitter {
|
||||
}
|
||||
|
||||
destroy() {
|
||||
super.removeAllListeners();
|
||||
|
||||
if (!this.skipEnvironmentObservers) {
|
||||
this.objectUnsubscribes.forEach(unsubscribe => {
|
||||
unsubscribe();
|
||||
@ -96,6 +94,7 @@ class ActionCollection extends EventEmitter {
|
||||
}
|
||||
|
||||
this.emit('destroy', this.view);
|
||||
this.removeAllListeners();
|
||||
}
|
||||
|
||||
getVisibleActions() {
|
||||
|
@ -339,6 +339,8 @@ define([
|
||||
|
||||
return provider.request.apply(provider, arguments)
|
||||
.catch((rejected) => {
|
||||
console.log('telemetryAPI rejected!!!!!');
|
||||
console.log(rejected);
|
||||
if (rejected.name !== 'AbortError') {
|
||||
this.openmct.notifications.error('Error requesting telemetry data, see console for details');
|
||||
console.error(rejected);
|
||||
|
@ -168,7 +168,7 @@ export default class StatusAPI extends EventEmitter {
|
||||
*/
|
||||
async resetStatusForRole(role) {
|
||||
const provider = this.#userAPI.getProvider();
|
||||
const defaultStatus = await this.getDefaultStatus();
|
||||
const defaultStatus = await this.getDefaultStatusForRole(role);
|
||||
|
||||
if (provider.setStatusForRole) {
|
||||
return provider.setStatusForRole(role, defaultStatus);
|
||||
|
@ -136,8 +136,8 @@ export default {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
const conditionSetIdentifier = domainObject.configuration.objectStyles.conditionSetIdentifier;
|
||||
if (this.conditionSetIdentifier !== conditionSetIdentifier) {
|
||||
const conditionSetIdentifier = domainObject.configuration?.objectStyles?.conditionSetIdentifier;
|
||||
if (conditionSetIdentifier && this.conditionSetIdentifier !== conditionSetIdentifier) {
|
||||
this.conditionSetIdentifier = conditionSetIdentifier;
|
||||
}
|
||||
|
||||
|
@ -128,6 +128,30 @@ export default class ExportAsJSONAction {
|
||||
|
||||
return copyOfChild;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {object} child
|
||||
* @param {object} parent
|
||||
* @returns {object}
|
||||
*/
|
||||
_rewriteLinkForReference(child, parent) {
|
||||
const childId = this._getId(child);
|
||||
this.externalIdentifiers.push(childId);
|
||||
const copyOfChild = JSON.parse(JSON.stringify(child));
|
||||
|
||||
copyOfChild.identifier.key = uuid();
|
||||
const newIdString = this._getId(copyOfChild);
|
||||
const parentId = this._getId(parent);
|
||||
|
||||
this.idMap[childId] = newIdString;
|
||||
copyOfChild.location = null;
|
||||
parent.configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier;
|
||||
this.tree[newIdString] = copyOfChild;
|
||||
this.tree[parentId].configuration.objectStyles.conditionSetIdentifier = copyOfChild.identifier;
|
||||
|
||||
return copyOfChild;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@ -159,23 +183,27 @@ export default class ExportAsJSONAction {
|
||||
"rootId": this._getId(this.root)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {object} parent
|
||||
*/
|
||||
_write(parent) {
|
||||
this.calls++;
|
||||
//conditional object styles are not saved on the composition, so we need to check for them
|
||||
let childObjectReferenceId = parent.configuration?.objectStyles?.conditionSetIdentifier;
|
||||
|
||||
const composition = this.openmct.composition.get(parent);
|
||||
if (composition !== undefined) {
|
||||
composition.load()
|
||||
.then((children) => {
|
||||
children.forEach((child, index) => {
|
||||
// Only export if object is creatable
|
||||
// Only export if object is creatable
|
||||
if (this._isCreatableAndPersistable(child)) {
|
||||
// Prevents infinite export of self-contained objs
|
||||
// Prevents infinite export of self-contained objs
|
||||
if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) {
|
||||
// If object is a link to something absent from
|
||||
// tree, generate new id and treat as new object
|
||||
// If object is a link to something absent from
|
||||
// tree, generate new id and treat as new object
|
||||
if (this._isLinkedObject(child, parent)) {
|
||||
child = this._rewriteLink(child, parent);
|
||||
} else {
|
||||
@ -186,18 +214,41 @@ export default class ExportAsJSONAction {
|
||||
}
|
||||
}
|
||||
});
|
||||
this.calls--;
|
||||
if (this.calls === 0) {
|
||||
this._rewriteReferences();
|
||||
this._saveAs(this._wrapTree());
|
||||
}
|
||||
this._decrementCallsAndSave();
|
||||
});
|
||||
} else {
|
||||
this.calls--;
|
||||
if (this.calls === 0) {
|
||||
this._rewriteReferences();
|
||||
this._saveAs(this._wrapTree());
|
||||
}
|
||||
} else if (!childObjectReferenceId) {
|
||||
this._decrementCallsAndSave();
|
||||
}
|
||||
|
||||
if (childObjectReferenceId) {
|
||||
this.openmct.objects.get(childObjectReferenceId)
|
||||
.then((child) => {
|
||||
// Only export if object is creatable
|
||||
if (this._isCreatableAndPersistable(child)) {
|
||||
// Prevents infinite export of self-contained objs
|
||||
if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) {
|
||||
// If object is a link to something absent from
|
||||
// tree, generate new id and treat as new object
|
||||
if (this._isLinkedObject(child, parent)) {
|
||||
child = this._rewriteLinkForReference(child, parent);
|
||||
} else {
|
||||
this.tree[this._getId(child)] = child;
|
||||
}
|
||||
|
||||
this._write(child);
|
||||
}
|
||||
}
|
||||
|
||||
this._decrementCallsAndSave();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_decrementCallsAndSave() {
|
||||
this.calls--;
|
||||
if (this.calls === 0) {
|
||||
this._rewriteReferences();
|
||||
this._saveAs(this._wrapTree());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,4 +322,57 @@ describe('Export as JSON plugin', () => {
|
||||
|
||||
exportAsJSONAction.invoke([parent]);
|
||||
});
|
||||
|
||||
it('ExportAsJSONAction exports object references from tree', (done) => {
|
||||
const parent = {
|
||||
composition: [],
|
||||
configuration: {
|
||||
objectStyles: {
|
||||
conditionSetIdentifier: {
|
||||
key: 'child',
|
||||
namespace: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
identifier: {
|
||||
key: 'parent',
|
||||
namespace: ''
|
||||
},
|
||||
name: 'Parent',
|
||||
type: 'folder',
|
||||
modified: 1503598129176,
|
||||
location: 'mine',
|
||||
persisted: 1503598129176
|
||||
};
|
||||
|
||||
const child = {
|
||||
composition: [],
|
||||
identifier: {
|
||||
key: 'child',
|
||||
namespace: ''
|
||||
},
|
||||
name: 'Child',
|
||||
type: 'folder',
|
||||
modified: 1503598132428,
|
||||
location: null,
|
||||
persisted: 1503598132428
|
||||
};
|
||||
|
||||
spyOn(openmct.objects, 'get').and.callFake(object => {
|
||||
return Promise.resolve(child);
|
||||
});
|
||||
|
||||
spyOn(exportAsJSONAction, '_saveAs').and.callFake(completedTree => {
|
||||
expect(Object.keys(completedTree).length).toBe(2);
|
||||
const conditionSetId = Object.keys(completedTree.openmct)[1];
|
||||
expect(Object.prototype.hasOwnProperty.call(completedTree, 'openmct')).toBeTruthy();
|
||||
expect(Object.prototype.hasOwnProperty.call(completedTree, 'rootId')).toBeTruthy();
|
||||
expect(Object.prototype.hasOwnProperty.call(completedTree.openmct, 'parent')).toBeTruthy();
|
||||
expect(completedTree.openmct[conditionSetId].name).toBe('Child');
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
exportAsJSONAction.invoke([parent]);
|
||||
});
|
||||
});
|
||||
|
@ -14,6 +14,8 @@
|
||||
type="range"
|
||||
min="0"
|
||||
max="500"
|
||||
draggable="true"
|
||||
@dragstart.stop.prevent
|
||||
@change="notifyFiltersChanged"
|
||||
@input="notifyFiltersChanged"
|
||||
>
|
||||
@ -24,6 +26,8 @@
|
||||
type="range"
|
||||
min="0"
|
||||
max="500"
|
||||
draggable="true"
|
||||
@dragstart.stop.prevent
|
||||
@change="notifyFiltersChanged"
|
||||
@input="notifyFiltersChanged"
|
||||
>
|
||||
|
@ -21,7 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="h-local-controls h-local-controls--overlay-content h-local-controls--menus-aligned c-local-controls--show-on-hover">
|
||||
<div
|
||||
class="h-local-controls h-local-controls--overlay-content h-local-controls--menus-aligned c-local-controls--show-on-hover"
|
||||
role="toolbar"
|
||||
aria-label="Image controls"
|
||||
>
|
||||
<imagery-view-menu-switcher
|
||||
:icon-class="'icon-brightness'"
|
||||
:title="'Brightness and contrast'"
|
||||
|
@ -30,7 +30,7 @@ export default {
|
||||
this.timeSystemChange = this.timeSystemChange.bind(this);
|
||||
this.setDataTimeContext = this.setDataTimeContext.bind(this);
|
||||
this.setDataTimeContext();
|
||||
this.openmct.objectViews.on('clearData', this.clearData);
|
||||
this.openmct.objectViews.on('clearData', this.dataCleared);
|
||||
|
||||
// set
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
@ -44,8 +44,11 @@ export default {
|
||||
this.timeKey = this.timeSystem.key;
|
||||
this.timeFormatter = this.getFormatter(this.timeKey);
|
||||
|
||||
// kickoff
|
||||
this.subscribe();
|
||||
this.telemetryCollection = this.openmct.telemetry.requestCollection(this.domainObject, {});
|
||||
this.telemetryCollection.on('add', this.dataAdded);
|
||||
this.telemetryCollection.on('remove', this.dataRemoved);
|
||||
this.telemetryCollection.on('clear', this.dataCleared);
|
||||
this.telemetryCollection.load();
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unsubscribe) {
|
||||
@ -54,9 +57,31 @@ export default {
|
||||
}
|
||||
|
||||
this.stopFollowingDataTimeContext();
|
||||
this.openmct.objectViews.off('clearData', this.clearData);
|
||||
this.openmct.objectViews.off('clearData', this.dataCleared);
|
||||
|
||||
this.telemetryCollection.off('add', this.dataAdded);
|
||||
this.telemetryCollection.off('remove', this.dataRemoved);
|
||||
this.telemetryCollection.off('clear', this.dataCleared);
|
||||
|
||||
this.telemetryCollection.destroy();
|
||||
},
|
||||
methods: {
|
||||
dataAdded(dataToAdd) {
|
||||
const normalizedDataToAdd = dataToAdd.map(datum => this.normalizeDatum(datum));
|
||||
this.imageHistory = this.imageHistory.concat(normalizedDataToAdd);
|
||||
},
|
||||
dataCleared() {
|
||||
this.imageHistory = [];
|
||||
},
|
||||
dataRemoved(dataToRemove) {
|
||||
this.imageHistory = this.imageHistory.filter(existingDatum => {
|
||||
const shouldKeep = dataToRemove.some(datumToRemove => {
|
||||
return (existingDatum.utc !== datumToRemove.utc);
|
||||
});
|
||||
|
||||
return shouldKeep;
|
||||
});
|
||||
},
|
||||
setDataTimeContext() {
|
||||
this.stopFollowingDataTimeContext();
|
||||
this.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||
@ -70,19 +95,6 @@ export default {
|
||||
this.timeContext.off('timeSystem', this.timeSystemChange);
|
||||
}
|
||||
},
|
||||
isDatumValid(datum) {
|
||||
//TODO: Add a check to see if there are duplicate images (identical image timestamp and url subsequently)
|
||||
if (!datum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const datumTimeCheck = this.parseTime(datum);
|
||||
const bounds = this.timeContext.bounds();
|
||||
|
||||
const isOutOfBounds = datumTimeCheck < bounds.start || datumTimeCheck > bounds.end;
|
||||
|
||||
return !isOutOfBounds;
|
||||
},
|
||||
formatImageUrl(datum) {
|
||||
if (!datum) {
|
||||
return;
|
||||
@ -124,40 +136,6 @@ export default {
|
||||
// forcibly reset the imageContainer size to prevent an aspect ratio distortion
|
||||
delete this.imageContainerWidth;
|
||||
delete this.imageContainerHeight;
|
||||
|
||||
return this.requestHistory();
|
||||
},
|
||||
async requestHistory() {
|
||||
this.requestCount++;
|
||||
const requestId = this.requestCount;
|
||||
const bounds = this.timeContext.bounds();
|
||||
|
||||
const data = await this.openmct.telemetry
|
||||
.request(this.domainObject, bounds) || [];
|
||||
// wait until new request resolves to do comparison
|
||||
if (this.requestCount !== requestId) {
|
||||
return this.imageHistory = [];
|
||||
}
|
||||
|
||||
const imagery = data.filter(this.isDatumValid).map(this.normalizeDatum);
|
||||
this.imageHistory = imagery;
|
||||
},
|
||||
clearData(domainObjectToClear) {
|
||||
// global clearData button is accepted therefore no truthy check on inputted param
|
||||
const clearDataForObjectSelected = Boolean(domainObjectToClear);
|
||||
if (clearDataForObjectSelected) {
|
||||
const idsEqual = this.openmct.objects.areIdsEqual(
|
||||
domainObjectToClear.identifier,
|
||||
this.domainObject.identifier
|
||||
);
|
||||
if (!idsEqual) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// splice array to encourage garbage collection
|
||||
this.imageHistory.splice(0, this.imageHistory.length);
|
||||
|
||||
},
|
||||
timeSystemChange() {
|
||||
this.timeSystem = this.timeContext.timeSystem();
|
||||
@ -165,22 +143,7 @@ export default {
|
||||
this.timeFormatter = this.getFormatter(this.timeKey);
|
||||
this.durationFormatter = this.getFormatter(this.timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
||||
},
|
||||
subscribe() {
|
||||
this.unsubscribe = this.openmct.telemetry
|
||||
.subscribe(this.domainObject, (datum) => {
|
||||
let parsedTimestamp = this.parseTime(datum);
|
||||
let bounds = this.timeContext.bounds();
|
||||
if (!(parsedTimestamp >= bounds.start && parsedTimestamp <= bounds.end)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.isDatumValid(datum)) {
|
||||
this.imageHistory.push(this.normalizeDatum(datum));
|
||||
}
|
||||
});
|
||||
},
|
||||
normalizeDatum(datum) {
|
||||
|
||||
const formattedTime = this.formatTime(datum);
|
||||
const url = this.formatImageUrl(datum);
|
||||
const time = this.parseTime(formattedTime);
|
||||
|
@ -88,6 +88,7 @@ describe("The Imagery View Layouts", () => {
|
||||
let openmct;
|
||||
let parent;
|
||||
let child;
|
||||
let historicalProvider;
|
||||
let imageTelemetry = generateTelemetry(START - TEN_MINUTES, COUNT);
|
||||
let imageryObject = {
|
||||
identifier: {
|
||||
@ -122,50 +123,6 @@ describe("The Imagery View Layouts", () => {
|
||||
"priority": 3
|
||||
},
|
||||
"source": "url"
|
||||
// "relatedTelemetry": {
|
||||
// "heading": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "heading",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// },
|
||||
// "roll": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "roll",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// },
|
||||
// "pitch": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "pitch",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// },
|
||||
// "cameraPan": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "cameraPan",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// },
|
||||
// "cameraTilt": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "cameraTilt",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// },
|
||||
// "sunOrientation": {
|
||||
// "comparisonFunction": comparisonFunction,
|
||||
// "historical": {
|
||||
// "telemetryObjectId": "sunOrientation",
|
||||
// "valueKey": "value"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
},
|
||||
{
|
||||
"name": "Name",
|
||||
@ -209,6 +166,13 @@ describe("The Imagery View Layouts", () => {
|
||||
telemetryPromiseResolve = resolve;
|
||||
});
|
||||
|
||||
historicalProvider = {
|
||||
request: () => {
|
||||
return Promise.resolve(imageTelemetry);
|
||||
}
|
||||
};
|
||||
spyOn(openmct.telemetry, 'findRequestProvider').and.returnValue(historicalProvider);
|
||||
|
||||
spyOn(openmct.telemetry, 'request').and.callFake(() => {
|
||||
telemetryPromiseResolve(imageTelemetry);
|
||||
|
||||
@ -584,6 +548,34 @@ describe("The Imagery View Layouts", () => {
|
||||
expect(imageSizeAfter.width).toBeLessThan(imageSizeBefore.width);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should reset the brightness and contrast when clicking the reset button', async () => {
|
||||
const viewInstance = imageryView._getInstance();
|
||||
await Vue.nextTick();
|
||||
|
||||
// Save the original brightness and contrast values
|
||||
const origBrightness = viewInstance.$refs.ImageryContainer.filters.brightness;
|
||||
const origContrast = viewInstance.$refs.ImageryContainer.filters.contrast;
|
||||
|
||||
// Change them to something else (default: 100)
|
||||
viewInstance.$refs.ImageryContainer.setFilters({
|
||||
brightness: 200,
|
||||
contrast: 200
|
||||
});
|
||||
await Vue.nextTick();
|
||||
|
||||
// Verify that the values actually changed
|
||||
expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(200);
|
||||
expect(viewInstance.$refs.ImageryContainer.filters.contrast).toBe(200);
|
||||
|
||||
// Click the reset button
|
||||
parent.querySelector('.t-btn-reset').click();
|
||||
await Vue.nextTick();
|
||||
|
||||
// Verify that the values were reset
|
||||
expect(viewInstance.$refs.ImageryContainer.filters.brightness).toBe(origBrightness);
|
||||
expect(viewInstance.$refs.ImageryContainer.filters.contrast).toBe(origContrast);
|
||||
});
|
||||
});
|
||||
|
||||
describe("imagery time strip view", () => {
|
||||
@ -598,6 +590,20 @@ describe("The Imagery View Layouts", () => {
|
||||
end: START + (5 * ONE_MINUTE)
|
||||
});
|
||||
|
||||
const mockClock = jasmine.createSpyObj("clock", [
|
||||
"on",
|
||||
"off",
|
||||
"currentValue"
|
||||
]);
|
||||
mockClock.key = 'mockClock';
|
||||
mockClock.currentValue.and.returnValue(1);
|
||||
|
||||
openmct.time.addClock(mockClock);
|
||||
openmct.time.clock('mockClock', {
|
||||
start: START - (5 * ONE_MINUTE),
|
||||
end: START + (5 * ONE_MINUTE)
|
||||
});
|
||||
|
||||
openmct.router.path = [{
|
||||
identifier: {
|
||||
key: 'test-timestrip',
|
||||
@ -632,7 +638,7 @@ describe("The Imagery View Layouts", () => {
|
||||
it("on mount should show imagery within the given bounds", (done) => {
|
||||
Vue.nextTick(() => {
|
||||
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
|
||||
expect(imageElements.length).toEqual(6);
|
||||
expect(imageElements.length).toEqual(5);
|
||||
done();
|
||||
});
|
||||
});
|
||||
@ -652,5 +658,46 @@ describe("The Imagery View Layouts", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should remove images when clock advances", async () => {
|
||||
openmct.time.tick(ONE_MINUTE * 2);
|
||||
await Vue.nextTick();
|
||||
await Vue.nextTick();
|
||||
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
|
||||
expect(imageElements.length).toEqual(4);
|
||||
});
|
||||
|
||||
it("should remove images when start bounds shorten", async () => {
|
||||
openmct.time.timeSystem('utc', {
|
||||
start: START,
|
||||
end: START + (5 * ONE_MINUTE)
|
||||
});
|
||||
await Vue.nextTick();
|
||||
await Vue.nextTick();
|
||||
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
|
||||
expect(imageElements.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("should remove images when end bounds shorten", async () => {
|
||||
openmct.time.timeSystem('utc', {
|
||||
start: START - (5 * ONE_MINUTE),
|
||||
end: START - (2 * ONE_MINUTE)
|
||||
});
|
||||
await Vue.nextTick();
|
||||
await Vue.nextTick();
|
||||
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
|
||||
expect(imageElements.length).toEqual(4);
|
||||
});
|
||||
|
||||
it("should remove images when both bounds shorten", async () => {
|
||||
openmct.time.timeSystem('utc', {
|
||||
start: START - (2 * ONE_MINUTE),
|
||||
end: START + (2 * ONE_MINUTE)
|
||||
});
|
||||
await Vue.nextTick();
|
||||
await Vue.nextTick();
|
||||
const imageElements = parent.querySelectorAll('.c-imagery-tsv__image-wrapper');
|
||||
expect(imageElements.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -82,12 +82,14 @@ export default class ImportAsJSONAction {
|
||||
* @param {object} seen
|
||||
*/
|
||||
_deepInstantiate(parent, tree, seen) {
|
||||
if (this.openmct.composition.get(parent)) {
|
||||
let objectIdentifiers = this._getObjectReferenceIds(parent);
|
||||
|
||||
if (objectIdentifiers.length) {
|
||||
let newObj;
|
||||
|
||||
seen.push(parent.id);
|
||||
|
||||
parent.composition.forEach(async (childId) => {
|
||||
objectIdentifiers.forEach(async (childId) => {
|
||||
const keystring = this.openmct.objects.makeKeyString(childId);
|
||||
if (!tree[keystring] || seen.includes(keystring)) {
|
||||
return;
|
||||
@ -101,6 +103,27 @@ export default class ImportAsJSONAction {
|
||||
}, this);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
* @param {object} parent
|
||||
* @returns [identifiers]
|
||||
*/
|
||||
_getObjectReferenceIds(parent) {
|
||||
let objectIdentifiers = [];
|
||||
|
||||
let parentComposition = this.openmct.composition.get(parent);
|
||||
if (parentComposition) {
|
||||
objectIdentifiers = Array.from(parentComposition.domainObject.composition);
|
||||
}
|
||||
|
||||
//conditional object styles are not saved on the composition, so we need to check for them
|
||||
let parentObjectReference = parent.configuration?.objectStyles?.conditionSetIdentifier;
|
||||
if (parentObjectReference) {
|
||||
objectIdentifiers.push(parentObjectReference);
|
||||
}
|
||||
|
||||
return objectIdentifiers;
|
||||
}
|
||||
/**
|
||||
* @private
|
||||
* @param {object} tree
|
||||
|
@ -87,6 +87,7 @@
|
||||
:highlights="highlights"
|
||||
:show-limit-line-labels="showLimitLineLabels"
|
||||
@plotReinitializeCanvas="initCanvas"
|
||||
@chartLoaded="initialize"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -359,11 +360,6 @@ export default {
|
||||
this.setTimeContext();
|
||||
|
||||
this.loaded = true;
|
||||
|
||||
//We're referencing the canvas elements from the mct-chart in the initialize method.
|
||||
// So we need $nextTick to ensure the component is fully mounted before we can initialize stuff.
|
||||
this.$nextTick(this.initialize);
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.removeEventListener('keydown', this.handleKeyDown);
|
||||
|
@ -105,9 +105,8 @@ export default {
|
||||
let canvasEls = this.$parent.$refs.chartContainer.querySelectorAll("canvas");
|
||||
const mainCanvas = canvasEls[1];
|
||||
const overlayCanvas = canvasEls[0];
|
||||
if (this.initializeCanvas(mainCanvas, overlayCanvas)) {
|
||||
this.draw();
|
||||
}
|
||||
|
||||
const initialized = this.initializeCanvas(mainCanvas, overlayCanvas);
|
||||
|
||||
this.listenTo(this.config.series, 'add', this.onSeriesAdd, this);
|
||||
this.listenTo(this.config.series, 'remove', this.onSeriesRemove, this);
|
||||
@ -115,6 +114,12 @@ export default {
|
||||
this.listenTo(this.config.yAxis, 'change', this.updateLimitsAndDraw);
|
||||
this.listenTo(this.config.xAxis, 'change', this.updateLimitsAndDraw);
|
||||
this.config.series.forEach(this.onSeriesAdd, this);
|
||||
|
||||
if (initialized) {
|
||||
this.draw();
|
||||
}
|
||||
|
||||
this.$emit('chartLoaded');
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.destroy();
|
||||
|
@ -64,6 +64,7 @@ import YAxisForm from "./forms/YAxisForm.vue";
|
||||
import LegendForm from "./forms/LegendForm.vue";
|
||||
import eventHelpers from "../lib/eventHelpers";
|
||||
import configStore from "../configuration/ConfigStore";
|
||||
import _ from "lodash";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -125,15 +126,25 @@ export default {
|
||||
});
|
||||
if (index < 0) {
|
||||
index = stackedPlotObject.configuration.series.length;
|
||||
const configPath = `configuration.series[${index}]`;
|
||||
let newConfig = {
|
||||
identifier: config.identifier
|
||||
};
|
||||
_.set(newConfig, `${config.path}`, config.value);
|
||||
this.openmct.objects.mutate(
|
||||
stackedPlotObject,
|
||||
configPath,
|
||||
newConfig
|
||||
);
|
||||
} else {
|
||||
const configPath = `configuration.series[${index}].${config.path}`;
|
||||
this.openmct.objects.mutate(
|
||||
stackedPlotObject,
|
||||
configPath,
|
||||
config.value
|
||||
);
|
||||
}
|
||||
|
||||
const configPath = `configuration.series[${index}].${config.path}`;
|
||||
this.openmct.objects.mutate(
|
||||
stackedPlotObject,
|
||||
configPath,
|
||||
config.value
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -227,8 +227,9 @@ export default {
|
||||
|
||||
const path = objectPath(formField.objectPath);
|
||||
if (!_.isEqual(newVal, oldVal)) {
|
||||
// TODO: Why do we mutate yAxis twice, once directly, once via objects.mutate? Or are they different objects?
|
||||
// We mutate the model for the plots first PlotConfigurationModel - this triggers changes that affects the plot behavior
|
||||
this.yAxis.set(formKey, newVal);
|
||||
// Then we mutate the domain object configuration to persist the settings
|
||||
if (path) {
|
||||
if (!this.domainObject.configuration || !this.domainObject.configuration.series) {
|
||||
this.$emit('seriesUpdated', {
|
||||
|
@ -26,13 +26,13 @@
|
||||
class="c-plot c-plot--stacked holder holder-plot has-control-bar"
|
||||
:class="[plotLegendExpandedStateClass, plotLegendPositionClass]"
|
||||
>
|
||||
<plot-legend
|
||||
:cursor-locked="!!lockHighlightPoint"
|
||||
:series="seriesModels"
|
||||
:highlights="highlights"
|
||||
:legend="legend"
|
||||
@legendHoverChanged="legendHoverChanged"
|
||||
/>
|
||||
<!-- <plot-legend-->
|
||||
<!-- :cursor-locked="!!lockHighlightPoint"-->
|
||||
<!-- :series="seriesModels"-->
|
||||
<!-- :highlights="highlights"-->
|
||||
<!-- :legend="legend"-->
|
||||
<!-- @legendHoverChanged="legendHoverChanged"-->
|
||||
<!-- />-->
|
||||
<div class="l-view-section">
|
||||
<stacked-plot-item
|
||||
v-for="object in compositionObjects"
|
||||
@ -167,18 +167,6 @@ export default {
|
||||
const id = this.openmct.objects.makeKeyString(child.identifier);
|
||||
|
||||
this.$set(this.tickWidthMap, id, 0);
|
||||
const persistedConfig = this.domainObject.configuration.series && this.domainObject.configuration.series.find((seriesConfig) => {
|
||||
return this.openmct.objects.areIdsEqual(seriesConfig.identifier, child.identifier);
|
||||
});
|
||||
if (persistedConfig === undefined) {
|
||||
this.openmct.objects.mutate(
|
||||
this.domainObject,
|
||||
'configuration.series[' + this.compositionObjects.length + ']',
|
||||
{
|
||||
identifier: child.identifier
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this.compositionObjects.push(child);
|
||||
},
|
||||
@ -256,11 +244,13 @@ export default {
|
||||
this.highlights = data;
|
||||
},
|
||||
registerSeriesListeners(configId) {
|
||||
this.seriesConfig[configId] = this.getConfig(configId);
|
||||
this.listenTo(this.seriesConfig[configId].series, 'add', this.addSeries, this);
|
||||
this.listenTo(this.seriesConfig[configId].series, 'remove', this.removeSeries, this);
|
||||
// const config = this.getConfig(configId);
|
||||
// config.series.models.forEach(this.addSeries, this);
|
||||
|
||||
this.seriesConfig[configId].series.models.forEach(this.addSeries, this);
|
||||
// if (config.series.models.length === 0 || config.series.models[0].keyString !== configId) {
|
||||
// this.listenTo(config.series, 'add', this.addSeries, this);
|
||||
// this.listenTo(config.series, 'remove', this.removeSeries, this);
|
||||
// }
|
||||
},
|
||||
addSeries(series) {
|
||||
const index = this.seriesModels.length;
|
||||
|
@ -223,33 +223,36 @@ export default {
|
||||
const configId = this.openmct.objects.makeKeyString(this.childObject.identifier);
|
||||
let config = configStore.get(configId);
|
||||
if (!config) {
|
||||
const persistedConfig = this.domainObject.configuration.series.find((seriesConfig) => {
|
||||
let persistedSeriesConfig = this.domainObject.configuration.series.find((seriesConfig) => {
|
||||
return this.openmct.objects.areIdsEqual(seriesConfig.identifier, this.childObject.identifier);
|
||||
});
|
||||
if (persistedConfig) {
|
||||
config = new PlotConfigurationModel({
|
||||
id: configId,
|
||||
domainObject: {
|
||||
...this.childObject,
|
||||
configuration: {
|
||||
series: [
|
||||
{
|
||||
identifier: this.childObject.identifier,
|
||||
...persistedConfig.series
|
||||
}
|
||||
],
|
||||
yAxis: persistedConfig.yAxis
|
||||
|
||||
let domainObject = {
|
||||
...this.childObject
|
||||
};
|
||||
if (persistedSeriesConfig) {
|
||||
domainObject.configuration = {
|
||||
series: [
|
||||
{
|
||||
identifier: this.childObject.identifier,
|
||||
...persistedSeriesConfig.series
|
||||
}
|
||||
},
|
||||
openmct: this.openmct,
|
||||
palette: this.colorPalette,
|
||||
callback: (data) => {
|
||||
this.data = data;
|
||||
}
|
||||
});
|
||||
configStore.add(configId, config);
|
||||
],
|
||||
yAxis: persistedSeriesConfig.yAxis
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
config = new PlotConfigurationModel({
|
||||
id: configId,
|
||||
domainObject,
|
||||
openmct: this.openmct,
|
||||
palette: this.colorPalette,
|
||||
callback: (data) => {
|
||||
this.data = data;
|
||||
}
|
||||
});
|
||||
configStore.add(configId, config);
|
||||
}
|
||||
|
||||
return this.childObject;
|
||||
|
70
src/plugins/timeline/TimelineCompositionPolicy.js
Normal file
70
src/plugins/timeline/TimelineCompositionPolicy.js
Normal file
@ -0,0 +1,70 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2021, 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.
|
||||
*****************************************************************************/
|
||||
const ALLOWED_TYPES = [
|
||||
'telemetry.plot.overlay',
|
||||
'telemetry.plot.stacked',
|
||||
'plan'
|
||||
];
|
||||
const DISALLOWED_TYPES = [
|
||||
'telemetry.plot.bar-graph',
|
||||
'telemetry.plot.scatter-plot'
|
||||
];
|
||||
export default function TimelineCompositionPolicy(openmct) {
|
||||
function hasNumericTelemetry(domainObject, metadata) {
|
||||
const hasTelemetry = openmct.telemetry.isTelemetryObject(domainObject);
|
||||
if (!hasTelemetry || !metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return metadata.values().length > 0 && hasDomainAndRange(metadata);
|
||||
}
|
||||
|
||||
function hasDomainAndRange(metadata) {
|
||||
return (metadata.valuesForHints(['range']).length > 0
|
||||
&& metadata.valuesForHints(['domain']).length > 0);
|
||||
}
|
||||
|
||||
function hasImageTelemetry(domainObject, metadata) {
|
||||
if (!metadata) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return metadata.valuesForHints(['image']).length > 0;
|
||||
}
|
||||
|
||||
return {
|
||||
allow: function (parent, child) {
|
||||
if (parent.type === 'time-strip') {
|
||||
const metadata = openmct.telemetry.getMetadata(child);
|
||||
|
||||
if (!DISALLOWED_TYPES.includes(child.type)
|
||||
&& (hasNumericTelemetry(child, metadata) || hasImageTelemetry(child, metadata) || ALLOWED_TYPES.includes(child.type))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
@ -22,6 +22,7 @@
|
||||
|
||||
import TimelineViewProvider from './TimelineViewProvider';
|
||||
import timelineInterceptor from "./timelineInterceptor";
|
||||
import TimelineCompositionPolicy from "./TimelineCompositionPolicy";
|
||||
|
||||
export default function () {
|
||||
return function install(openmct) {
|
||||
@ -39,6 +40,8 @@ export default function () {
|
||||
}
|
||||
});
|
||||
timelineInterceptor(openmct);
|
||||
openmct.composition.addPolicy(new TimelineCompositionPolicy(openmct).allow);
|
||||
|
||||
openmct.objectViews.addProvider(new TimelineViewProvider(openmct));
|
||||
};
|
||||
}
|
||||
|
@ -62,6 +62,34 @@ describe('the plugin', function () {
|
||||
})
|
||||
}
|
||||
};
|
||||
let timelineObject = {
|
||||
"composition": [],
|
||||
configuration: {
|
||||
useIndependentTime: false,
|
||||
timeOptions: {
|
||||
mode: {
|
||||
key: 'fixed'
|
||||
},
|
||||
fixedOffsets: {
|
||||
start: 10,
|
||||
end: 11
|
||||
},
|
||||
clockOffsets: {
|
||||
start: -(30 * 60 * 1000),
|
||||
end: (30 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
},
|
||||
"name": "Some timestrip",
|
||||
"type": "time-strip",
|
||||
"location": "mine",
|
||||
"modified": 1631005183584,
|
||||
"persisted": 1631005183502,
|
||||
"identifier": {
|
||||
"namespace": "",
|
||||
"key": "b78e7e23-f2b8-4776-b1f0-3ff778f5c8a9"
|
||||
}
|
||||
};
|
||||
|
||||
beforeEach((done) => {
|
||||
mockObjectPath = [
|
||||
@ -134,28 +162,7 @@ describe('the plugin', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
testViewObject = {
|
||||
id: "test-object",
|
||||
identifier: {
|
||||
key: "test-object",
|
||||
namespace: ''
|
||||
},
|
||||
type: "time-strip",
|
||||
configuration: {
|
||||
useIndependentTime: false,
|
||||
timeOptions: {
|
||||
mode: {
|
||||
key: 'fixed'
|
||||
},
|
||||
fixedOffsets: {
|
||||
start: 10,
|
||||
end: 11
|
||||
},
|
||||
clockOffsets: {
|
||||
start: -(30 * 60 * 1000),
|
||||
end: (30 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
}
|
||||
...timelineObject
|
||||
};
|
||||
|
||||
const applicableViews = openmct.objectViews.get(testViewObject, mockObjectPath);
|
||||
@ -187,15 +194,7 @@ describe('the plugin', function () {
|
||||
|
||||
beforeEach(() => {
|
||||
timelineDomainObject = {
|
||||
identifier: {
|
||||
key: 'test-object',
|
||||
namespace: ''
|
||||
},
|
||||
type: 'time-strip',
|
||||
id: "test-object",
|
||||
configuration: {
|
||||
useIndependentTime: false
|
||||
},
|
||||
...timelineObject,
|
||||
composition: [
|
||||
{
|
||||
identifier: {
|
||||
@ -236,27 +235,10 @@ describe('the plugin', function () {
|
||||
describe('the independent time conductor', () => {
|
||||
let timelineView;
|
||||
let testViewObject = {
|
||||
id: "test-object",
|
||||
identifier: {
|
||||
key: "test-object",
|
||||
namespace: ''
|
||||
},
|
||||
type: "time-strip",
|
||||
...timelineObject,
|
||||
configuration: {
|
||||
useIndependentTime: true,
|
||||
timeOptions: {
|
||||
mode: {
|
||||
key: 'local'
|
||||
},
|
||||
fixedOffsets: {
|
||||
start: 10,
|
||||
end: 11
|
||||
},
|
||||
clockOffsets: {
|
||||
start: -(30 * 60 * 1000),
|
||||
end: (30 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
...timelineObject.configuration,
|
||||
useIndependentTime: true
|
||||
}
|
||||
};
|
||||
|
||||
@ -284,27 +266,15 @@ describe('the plugin', function () {
|
||||
describe('the independent time conductor - fixed', () => {
|
||||
let timelineView;
|
||||
let testViewObject2 = {
|
||||
...timelineObject,
|
||||
id: "test-object2",
|
||||
identifier: {
|
||||
key: "test-object2",
|
||||
namespace: ''
|
||||
},
|
||||
type: "time-strip",
|
||||
configuration: {
|
||||
useIndependentTime: true,
|
||||
timeOptions: {
|
||||
mode: {
|
||||
key: 'fixed'
|
||||
},
|
||||
fixedOffsets: {
|
||||
start: 10,
|
||||
end: 11
|
||||
},
|
||||
clockOffsets: {
|
||||
start: -(30 * 60 * 1000),
|
||||
end: (30 * 60 * 1000)
|
||||
}
|
||||
}
|
||||
...timelineObject.configuration,
|
||||
useIndependentTime: true
|
||||
}
|
||||
};
|
||||
|
||||
@ -328,4 +298,68 @@ describe('the plugin', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe("The timestrip composition policy", () => {
|
||||
let testObject;
|
||||
beforeEach(() => {
|
||||
testObject = {
|
||||
...timelineObject,
|
||||
composition: []
|
||||
};
|
||||
});
|
||||
|
||||
it("allows composition for plots", () => {
|
||||
const testTelemetryObject = {
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "test-object",
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
values: [{
|
||||
key: "some-key",
|
||||
name: "Some attribute",
|
||||
hints: {
|
||||
domain: 1
|
||||
}
|
||||
}, {
|
||||
key: "some-other-key",
|
||||
name: "Another attribute",
|
||||
hints: {
|
||||
range: 1
|
||||
}
|
||||
}]
|
||||
}
|
||||
};
|
||||
const composition = openmct.composition.get(testObject);
|
||||
expect(() => {
|
||||
composition.add(testTelemetryObject);
|
||||
}).not.toThrow();
|
||||
expect(testObject.composition.length).toBe(1);
|
||||
});
|
||||
|
||||
it("allows composition for plans", () => {
|
||||
const composition = openmct.composition.get(testObject);
|
||||
expect(() => {
|
||||
composition.add(planObject);
|
||||
}).not.toThrow();
|
||||
expect(testObject.composition.length).toBe(1);
|
||||
});
|
||||
|
||||
it("disallows composition for non time-based plots", () => {
|
||||
const barGraphObject = {
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "test-object"
|
||||
},
|
||||
type: "telemetry.plot.bar-graph",
|
||||
name: "Test Object"
|
||||
};
|
||||
const composition = openmct.composition.get(testObject);
|
||||
expect(() => {
|
||||
composition.add(barGraphObject);
|
||||
}).toThrow();
|
||||
expect(testObject.composition.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -43,14 +43,19 @@ export default class PauseTimerAction {
|
||||
|
||||
this.openmct.objects.mutate(domainObject, 'configuration', newConfiguration);
|
||||
}
|
||||
appliesTo(objectPath) {
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const domainObject = objectPath[0];
|
||||
if (!domainObject || !domainObject.configuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use object configuration timerState for viewless context menus,
|
||||
// otherwise manually show/hide based on the view's timerState
|
||||
const viewKey = view.key;
|
||||
const { timerState } = domainObject.configuration;
|
||||
|
||||
return domainObject.type === 'timer' && timerState === 'started';
|
||||
return viewKey
|
||||
? domainObject.type === 'timer'
|
||||
: domainObject.type === 'timer' && timerState === 'started';
|
||||
}
|
||||
}
|
||||
|
@ -44,14 +44,19 @@ export default class RestartTimerAction {
|
||||
|
||||
this.openmct.objects.mutate(domainObject, 'configuration', newConfiguration);
|
||||
}
|
||||
appliesTo(objectPath) {
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const domainObject = objectPath[0];
|
||||
if (!domainObject || !domainObject.configuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use object configuration timerState for viewless context menus,
|
||||
// otherwise manually show/hide based on the view's timerState
|
||||
const viewKey = view.key;
|
||||
const { timerState } = domainObject.configuration;
|
||||
|
||||
return domainObject.type === 'timer' && timerState !== 'stopped';
|
||||
return viewKey
|
||||
? domainObject.type === 'timer'
|
||||
: domainObject.type === 'timer' && timerState !== 'stopped';
|
||||
}
|
||||
}
|
||||
|
@ -63,14 +63,19 @@ export default class StartTimerAction {
|
||||
newConfiguration.pausedTime = undefined;
|
||||
this.openmct.objects.mutate(domainObject, 'configuration', newConfiguration);
|
||||
}
|
||||
appliesTo(objectPath) {
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const domainObject = objectPath[0];
|
||||
if (!domainObject || !domainObject.configuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use object configuration timerState for viewless context menus,
|
||||
// otherwise manually show/hide based on the view's timerState
|
||||
const viewKey = view.key;
|
||||
const { timerState } = domainObject.configuration;
|
||||
|
||||
return domainObject.type === 'timer' && timerState !== 'started';
|
||||
return viewKey
|
||||
? domainObject.type === 'timer'
|
||||
: domainObject.type === 'timer' && timerState !== 'started';
|
||||
}
|
||||
}
|
||||
|
@ -44,14 +44,19 @@ export default class StopTimerAction {
|
||||
|
||||
this.openmct.objects.mutate(domainObject, 'configuration', newConfiguration);
|
||||
}
|
||||
appliesTo(objectPath) {
|
||||
appliesTo(objectPath, view = {}) {
|
||||
const domainObject = objectPath[0];
|
||||
if (!domainObject || !domainObject.configuration) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use object configuration timerState for viewless context menus,
|
||||
// otherwise manually show/hide based on the view's timerState
|
||||
const viewKey = view.key;
|
||||
const { timerState } = domainObject.configuration;
|
||||
|
||||
return domainObject.type === 'timer' && timerState !== 'stopped';
|
||||
return viewKey
|
||||
? domainObject.type === 'timer'
|
||||
: domainObject.type === 'timer' && timerState !== 'stopped';
|
||||
}
|
||||
}
|
||||
|
@ -179,6 +179,15 @@ export default {
|
||||
return timerSign;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
timerState() {
|
||||
if (!this.viewActionsCollection) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.showOrHideAvailableActions();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
if (this.configuration && this.configuration.timerState === undefined) {
|
||||
@ -190,6 +199,9 @@ export default {
|
||||
this.unlisten = ticker.listen(() => {
|
||||
this.openmct.objects.refresh(this.domainObject);
|
||||
});
|
||||
|
||||
this.viewActionsCollection = this.openmct.actions.getActionsCollection(this.objectPath, this.currentView);
|
||||
this.showOrHideAvailableActions();
|
||||
});
|
||||
},
|
||||
beforeDestroy() {
|
||||
@ -228,6 +240,22 @@ export default {
|
||||
if (action) {
|
||||
action.invoke(this.objectPath, this.currentView);
|
||||
}
|
||||
},
|
||||
showOrHideAvailableActions() {
|
||||
switch (this.timerState) {
|
||||
case 'started':
|
||||
this.viewActionsCollection.hide(['timer.start']);
|
||||
this.viewActionsCollection.show(['timer.stop', 'timer.pause', 'timer.restart']);
|
||||
break;
|
||||
case 'paused':
|
||||
this.viewActionsCollection.hide(['timer.pause']);
|
||||
this.viewActionsCollection.show(['timer.stop', 'timer.start', 'timer.restart']);
|
||||
break;
|
||||
case 'stopped':
|
||||
this.viewActionsCollection.hide(['timer.stop', 'timer.pause', 'timer.restart']);
|
||||
this.viewActionsCollection.show(['timer.start']);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -283,34 +283,32 @@ $bg-icon-info: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3
|
||||
$bg-icon-plus: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M480,192H320V32A32.1,32.1,0,0,0,288,0H224a32.1,32.1,0,0,0-32,32V192H32A32.1,32.1,0,0,0,0,224v64a32.1,32.1,0,0,0,32,32H192V480a32.1,32.1,0,0,0,32,32h64a32.1,32.1,0,0,0,32-32V320H480a32.1,32.1,0,0,0,32-32V224A32.1,32.1,0,0,0,480,192Z' transform='translate(0)'/%3e%3c/svg%3e");
|
||||
$bg-icon-grippy-ew: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M416 0v512h-64V0zM288 0v512h-64V0zM160 0v512H96V0z'/%3e%3c/svg%3e");
|
||||
$bg-icon-chain-links: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M479.2 32.8C457.3 10.9 428.7 0 400 0c-28.7 0-57.3 10.9-79.2 32.8l-64 64c-37 37-42.7 93.5-17 136.5l-6.4 6.4C215.7 229.3 195.9 224 176 224c-28.7 0-57.3 10.9-79.2 32.8l-64 64c-43.7 43.7-43.7 114.7 0 158.4C54.7 501.1 83.3 512 112 512c28.7 0 57.3-10.9 79.2-32.8l64-64c37-37 42.7-93.5 17-136.5l6.4-6.4c17.6 10.5 37.5 15.8 57.3 15.8 28.7 0 57.3-10.9 79.2-32.8l64-64c43.8-43.8 43.8-114.8.1-158.5zM209.9 369.9l-64 64c-9 9.1-21.1 14.1-33.9 14.1-12.8 0-24.9-5-33.9-14.1-18.7-18.7-18.7-49.2 0-67.9l64-64c9.1-9.1 21.1-14.1 33.9-14.1 2.8 0 5.6.3 8.4.7l-27.8 27.8c-5.2 5.2-8.1 12.1-8.1 19.4s2.9 14.3 8.1 19.4c5.2 5.2 12.1 8.1 19.4 8.1s14.3-2.9 19.4-8.1l27.8-27.8c2.7 15.2-1.8 31.1-13.3 42.5zm224-224l-64 64c-9 9.1-21.1 14.1-33.9 14.1-2.8 0-5.6-.3-8.4-.7l27.8-27.8c5.2-5.2 8.1-12.1 8.1-19.4s-2.9-14.3-8.1-19.4c-5.2-5.2-12.1-8.1-19.4-8.1s-14.3 2.9-19.4 8.1l-27.8 27.8c-2.6-14.9 1.8-30.8 13.3-42.3l64-64C375.1 69 387.2 64 400 64s24.9 5 33.9 14.1c18.8 18.7 18.8 49.1 0 67.8z'/%3e%3c/svg%3e");
|
||||
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M288 32H160l160 160H174.872C152.74 153.742 111.377 128 64 128H0v256h64c47.377 0 88.74-25.742 110.872-64H320L160 480h128l224-224L288 32z'/%3e%3c/svg%3e");
|
||||
$bg-icon-database: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 0C148.6 0 56.6 66.2 18.6 160H64c28.4 0 54 12.4 71.5 32H256l-96-96h128l160 160-160 160H160l96-96H135.5C118 339.6 92.4 352 64 352H18.6c38 93.8 129.9 160 237.4 160 141.4 0 256-114.6 256-256S397.4 0 256 0z'/%3e%3c/svg%3e");
|
||||
$bg-icon-database-query: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M96 0C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h32V0H96zM192 0h128v512H192zM416 0h-32v352h128V96c0-52.8-43.2-96-96-96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-dataset: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm135 345c-6.4 11.1-18.3 18-31.2 18-6.3 0-12.5-1.7-18-4.8l-110.9-64-.1-.1c-.4-.2-.8-.5-1.2-.7l-.4-.3-.9-.6-.6-.5-.6-.5-.9-.7-.3-.3c-.4-.3-.7-.6-1.1-.9-2.5-2.3-4.7-5-6.5-7.9-.1-.2-.3-.5-.4-.7s-.3-.5-.4-.7c-1.6-3-2.9-6.2-3.6-9.6v-.1c-.1-.5-.2-.9-.3-1.4 0-.1 0-.3-.1-.4-.1-.3-.1-.7-.1-1.1s-.1-.5-.1-.8 0-.5-.1-.8-.1-.8-.1-1.1v-.5-1.4V81c0-19.9 16.1-36 36-36s36 16.1 36 36v161.2l92.9 53.6c17.1 10 22.9 32 13 49.2z'/%3e%3c/svg%3e");
|
||||
$bg-icon-datatable: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.615 256 0 213.019 0 160v256c0 53.019 114.615 96 256 96s256-42.981 256-96V160c0 53.019-114.615 96-256 96z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
|
||||
$bg-icon-dictionary: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M341.76 409.643C316.369 423.871 287.118 432 256 432c-97.047 0-176-78.953-176-176S158.953 80 256 80s176 78.953 176 176c0 31.118-8.129 60.369-22.357 85.76l95.846 95.846C509.747 430.661 512 423.429 512 416V96c0-53.019-114.615-96-256-96S0 42.981 0 96v320c0 53.019 114.615 96 256 96 63.055 0 120.774-8.554 165.388-22.73l-79.628-79.627z'/%3e%3cpath fill='%23000000' d='M176 256c0 44.112 35.888 80 80 80s80-35.888 80-80-35.888-80-80-80-80 35.888-80 80z'/%3e%3c/svg%3e");
|
||||
$bg-icon-folder: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64zM160 448H96V288h64v160zm128 0h-64V288h64v160zm128 0h-64V288h64v160z'/%3e%3c/svg%3e");
|
||||
$bg-icon-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.6 256 0 213 0 160v256c0 53 114.6 96 256 96s256-43 256-96V160c0 53-114.6 96-256 96zm192 31.5v128c-18.3 7.8-39.9 14.4-64 19.7v-128c24.1-5.3 45.7-11.9 64-19.7zm-320 19.7v128c-24.1-5.2-45.7-11.9-64-19.7v-128c18.3 7.8 39.9 14.4 64 19.7zM192 445V317c20.5 2 41.9 3 64 3s43.5-1.1 64-3v128c-20.5 2-41.9 3-64 3s-43.5-1.1-64-3z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
|
||||
$bg-icon-layout: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M416 320c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96v160l-64-32-64 32V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96v-96c0 52.8-43.2 96-96 96H96v-96h320z'/%3e%3c/svg%3e");
|
||||
$bg-icon-object: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-object-unknown: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm0 448H64V64h384v384z'/%3e%3cpath fill='%23000000' d='M160 128l-64 64v224h320V256l-64-64-64 64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-packet: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M224 0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h128V0zM416 0H288v288.832h224V96c0-52.8-43.2-96-96-96zM288 512h128c52.8 0 96-43.2 96-96v-64.832H288V512z'/%3e%3c/svg%3e");
|
||||
$bg-icon-page: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 512l256-160V160L255.99 0 0 160v192l256 160zm0-416l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-plot-overlay: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M255-1L-1 159v192l256 160 256-160V159L255-1zm37.7 430.6c-10.6 10.4-23 15.4-38 15.4-15.6 0-28.1-4.9-38.1-14.8-10-10-14.8-22.4-14.8-38.1 0-15.2 5.1-27.6 15.5-38.1s22.6-15.6 37.4-15.6c14.8 0 27.1 5.2 37.8 16 10.7 10.8 15.9 23.2 15.9 38-.1 14.5-5.4 27-15.7 37.2zm26.4-156.3c-11.8 5.9-18.7 11-21.7 16.2-1.8 3.1-3 7.4-3.7 13.4v20.5H213v-22.1c0-20.1 2.2-34.9 6.5-44 4-8.6 11.3-15.1 22.4-20l17.4-7.7c16-7.1 24.1-17.6 24.1-31.4 0-8-3-15.2-8.6-20.9-5.6-5.6-12.8-8.6-20.8-8.6-12 0-27.2 5-31.4 28.7l-1.1 6.1H148l.7-8.1c2-22.3 8.5-41.2 19.4-56.1 9.8-13.5 22.8-24.3 38.5-32.3 15.7-8 32.3-12 49.1-12 30.3 0 55.1 9.7 75.7 29.8 20.6 20 30.6 44 30.6 73.6 0 35.4-14.4 60.7-42.9 74.9z'/%3e%3c/svg%3e");
|
||||
$bg-icon-plot-stacked: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 0L0 160v256c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V160L256 0zm0 96l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-session: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M352 256c-52.8 0-96-43.2-96-96V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V256H352z'/%3e%3cpath fill='%23000000' d='M384 192h128L320 0v128c0 35.2 28.8 64 64 64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M415 0H97C43.65 0 0 43.65 0 97v203.41c7.09 9.32 12.83 14.17 16 15.42 7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73C403.71 188.64 440.64 124 496 124a69.55 69.55 0 0 1 16 1.87V97c0-53.35-43.65-97-97-97z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73C108.29 323.36 71.36 388 16 388a69.56 69.56 0 0 1-16-1.87V415c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97V211.59c-7.09-9.32-12.83-14.17-16-15.42z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-lad: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M44.8 156c12.49 0 24.48-13.26 42.76-35.09 22.71-27.14 51-60.91 98-60.91 22.32 0 43.31 7.73 62.4 23 14.34 11.45 25.58 25.21 36.46 38.53C303.63 145 314 156 326.4 156H512V97c0-53.35-43.65-97-97-97H97C43.65 0 0 43.65 0 97v59h44.8z'/%3e%3cpath fill='%23000000' d='M264.75 205.2c-14.12-11.32-25.26-25-36-38.14C211 145.32 199.37 132 185.6 132c-12.53 0-24.54 13.27-42.83 35.12-22.7 27.12-51 60.88-98 60.88H0v56h185.6c22 0 42.77 7.67 61.65 22.8 14.12 11.32 25.26 25 36 38.14C301 366.68 312.63 380 326.4 380c12.53 0 24.54-13.27 42.83-35.12 22.7-27.12 51-60.88 98-60.88H512v-56H326.4c-22.03 0-42.77-7.67-61.65-22.8z'/%3e%3cpath fill='%23000000' d='M467.2 356c-12.49 0-24.48 13.26-42.76 35.09-22.71 27.14-51 60.91-98 60.91-22.32 0-43.31-7.73-62.4-23-14.34-11.45-25.58-25.21-36.46-38.53C208.37 367 198 356 185.6 356H0v59c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97v-59h-44.8z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-lad-set: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M317.8 262.2c3.3 2.1 6.6 4.3 9.6 6.8l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l67.6-54c.1-2.4.1-4.7.1-7.1 0-26.1-3.9-51.2-11.1-74.9L423.5 243c-29.1 23.3-70.1 29.6-105.7 19.2zM124.3 317.1l60.2-48.2c29-23.2 70-29.6 105.6-19.2-3.3-2.1-6.6-4.3-9.6-6.8l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L103.5 243c-20 16-45.7 24-71.5 24-10.8 0-21.5-1.4-31.9-4.2v.8c2.5 1.7 5 3.4 7.3 5.3l60.2 48.2c14.9 11.9 41.9 11.9 56.7 0z'/%3e%3cpath fill='%23000000' d='M60.3 189.1l60.2-48.2c40.1-32.1 102.8-32.1 142.9 0l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l90.5-72.4C425.2 46.5 346 0 256 0 136.7 0 36.4 81.6 8 192.1c15.4 8.8 38.9 7.8 52.3-3zM344.5 371l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L167.5 371c-20 16-45.7 24-71.5 24-23.9 0-47.7-6.9-67.1-20.7C71.7 456.1 157.3 512 256 512s184.3-55.9 227.1-137.7c-40.2 28.7-99.9 27.6-138.6-3.3z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-realtime: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zM320 224H192v-96h128v96zm-128 32h128v96H192v-96zm-32 96H32v-96h128v96zm0-224v96H32v-96h128zM64 480c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h128v96H64zm128 0v-96h128v96H192zm288-32c0 8.5-3.3 16.5-9.4 22.6S456.5 480 448 480h-96v-96h128v64zm0-96H352v-96h128v96zm0-128H352v-96h128v96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-scrolling: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.7.1.1 28.7 0 64v384c.1 35.3 28.7 63.9 64 64h384c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM32 128h128v96H32v-96zm0 128h128v96H32v-96zm32 224c-17.6-.1-31.9-14.4-32-32v-64h128v96H64zm128 0v-96h128v96H192zm288-32c-.1 17.6-14.4 31.9-32 32h-96v-96h128v64zm0-192v96H192v-96h32v-32h-32v-96h288v96h-32v32h32z'/%3e%3cpath fill='%23000000' d='M391.2 273.7L336 246.1V160c0-8.8-7.2-16-16-16s-16 7.2-16 16v105.9l72.8 36.4c7.9 4 17.5.8 21.5-7.2 4-7.8.8-17.5-7.1-21.4z'/%3e%3c/svg%3e");
|
||||
$bg-icon-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M64 384V96c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64H128c-35.3-.1-63.9-28.7-64-64z'/%3e%3cpath fill='%23000000' d='M448 0H160c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM128 96h96v64h-96V96zm0 96h96v96h-96v-96zm32 192c-17.6-.1-31.9-14.4-32-32v-32h96v64h-64zm96 0v-64h96v64h-96zm224-32c-.1 17.6-14.4 31.9-32 32h-64v-64h96v32zm0-64H256V96h224v192z'/%3e%3cpath fill='%23000000' d='M416 240c8.8 0 16-7.2 16-16 0-6.9-4.4-13-10.9-15.2L384 196.5V144c0-8.8-7.2-16-16-16s-16 7.2-16 16v75.5l58.9 19.6c1.7.6 3.4.9 5.1.9z'/%3e%3c/svg%3e");
|
||||
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm135 345c-6.4 11.1-18.3 18-31.2 18-6.3 0-12.5-1.7-18-4.8l-110.9-64-.1-.1c-.4-.2-.8-.5-1.2-.7l-.4-.3-.9-.6-.6-.5-.6-.5-.9-.7-.3-.3c-.4-.3-.7-.6-1.1-.9-2.5-2.3-4.7-5-6.5-7.9-.1-.2-.3-.5-.4-.7s-.3-.5-.4-.7c-1.6-3-2.9-6.2-3.6-9.6v-.1c-.1-.5-.2-.9-.3-1.4 0-.1 0-.3-.1-.4-.1-.3-.1-.7-.1-1.1s-.1-.5-.1-.8 0-.5-.1-.8-.1-.8-.1-1.1v-.5-1.4V81c0-19.9 16.1-36 36-36s36 16.1 36 36v161.2l92.9 53.6c17.1 10 22.9 32 13 49.2z'/%3e%3c/svg%3e");
|
||||
$bg-icon-database: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.615 256 0 213.019 0 160v256c0 53.019 114.615 96 256 96s256-42.981 256-96V160c0 53.019-114.615 96-256 96z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
|
||||
$bg-icon-database-query: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M341.76 409.643C316.369 423.871 287.118 432 256 432c-97.047 0-176-78.953-176-176S158.953 80 256 80s176 78.953 176 176c0 31.118-8.129 60.369-22.357 85.76l95.846 95.846C509.747 430.661 512 423.429 512 416V96c0-53.019-114.615-96-256-96S0 42.981 0 96v320c0 53.019 114.615 96 256 96 63.055 0 120.774-8.554 165.388-22.73l-79.628-79.627z'/%3e%3cpath fill='%23000000' d='M176 256c0 44.112 35.888 80 80 80s80-35.888 80-80-35.888-80-80-80-80 35.888-80 80z'/%3e%3c/svg%3e");
|
||||
$bg-icon-dataset: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64zM160 448H96V288h64v160zm128 0h-64V288h64v160zm128 0h-64V288h64v160z'/%3e%3c/svg%3e");
|
||||
$bg-icon-datatable: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.6 256 0 213 0 160v256c0 53 114.6 96 256 96s256-43 256-96V160c0 53-114.6 96-256 96zm192 31.5v128c-18.3 7.8-39.9 14.4-64 19.7v-128c24.1-5.3 45.7-11.9 64-19.7zm-320 19.7v128c-24.1-5.2-45.7-11.9-64-19.7v-128c18.3 7.8 39.9 14.4 64 19.7zM192 445V317c20.5 2 41.9 3 64 3s43.5-1.1 64-3v128c-20.5 2-41.9 3-64 3s-43.5-1.1-64-3z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
|
||||
$bg-icon-dictionary: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M416 320c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96v160l-64-32-64 32V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96v-96c0 52.8-43.2 96-96 96H96v-96h320z'/%3e%3c/svg%3e");
|
||||
$bg-icon-folder: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm0 448H64V64h384v384z'/%3e%3cpath fill='%23000000' d='M160 128l-64 64v224h320V256l-64-64-64 64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-layout: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M224 0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h128V0zM416 0H288v288.832h224V96c0-52.8-43.2-96-96-96zM288 512h128c52.8 0 96-43.2 96-96v-64.832H288V512z'/%3e%3c/svg%3e");
|
||||
$bg-icon-object: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 512l256-160V160L255.99 0 0 160v192l256 160zm0-416l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-object-unknown: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M255-1L-1 159v192l256 160 256-160V159L255-1zm37.7 430.6c-10.6 10.4-23 15.4-38 15.4-15.6 0-28.1-4.9-38.1-14.8-10-10-14.8-22.4-14.8-38.1 0-15.2 5.1-27.6 15.5-38.1s22.6-15.6 37.4-15.6c14.8 0 27.1 5.2 37.8 16 10.7 10.8 15.9 23.2 15.9 38-.1 14.5-5.4 27-15.7 37.2zm26.4-156.3c-11.8 5.9-18.7 11-21.7 16.2-1.8 3.1-3 7.4-3.7 13.4v20.5H213v-22.1c0-20.1 2.2-34.9 6.5-44 4-8.6 11.3-15.1 22.4-20l17.4-7.7c16-7.1 24.1-17.6 24.1-31.4 0-8-3-15.2-8.6-20.9-5.6-5.6-12.8-8.6-20.8-8.6-12 0-27.2 5-31.4 28.7l-1.1 6.1H148l.7-8.1c2-22.3 8.5-41.2 19.4-56.1 9.8-13.5 22.8-24.3 38.5-32.3 15.7-8 32.3-12 49.1-12 30.3 0 55.1 9.7 75.7 29.8 20.6 20 30.6 44 30.6 73.6 0 35.4-14.4 60.7-42.9 74.9z'/%3e%3c/svg%3e");
|
||||
$bg-icon-packet: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 0L0 160v256c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V160L256 0zm0 96l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-page: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M352 256c-52.8 0-96-43.2-96-96V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V256H352z'/%3e%3cpath fill='%23000000' d='M384 192h128L320 0v128c0 35.2 28.8 64 64 64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-plot-overlay: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M415 0H97C43.65 0 0 43.65 0 97v203.41c7.09 9.32 12.83 14.17 16 15.42 7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73C403.71 188.64 440.64 124 496 124a69.55 69.55 0 0 1 16 1.87V97c0-53.35-43.65-97-97-97z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73C108.29 323.36 71.36 388 16 388a69.56 69.56 0 0 1-16-1.87V415c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97V211.59c-7.09-9.32-12.83-14.17-16-15.42z'/%3e%3c/svg%3e");
|
||||
$bg-icon-plot-stacked: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M44.8 156c12.49 0 24.48-13.26 42.76-35.09 22.71-27.14 51-60.91 98-60.91 22.32 0 43.31 7.73 62.4 23 14.34 11.45 25.58 25.21 36.46 38.53C303.63 145 314 156 326.4 156H512V97c0-53.35-43.65-97-97-97H97C43.65 0 0 43.65 0 97v59h44.8z'/%3e%3cpath fill='%23000000' d='M264.75 205.2c-14.12-11.32-25.26-25-36-38.14C211 145.32 199.37 132 185.6 132c-12.53 0-24.54 13.27-42.83 35.12-22.7 27.12-51 60.88-98 60.88H0v56h185.6c22 0 42.77 7.67 61.65 22.8 14.12 11.32 25.26 25 36 38.14C301 366.68 312.63 380 326.4 380c12.53 0 24.54-13.27 42.83-35.12 22.7-27.12 51-60.88 98-60.88H512v-56H326.4c-22.03 0-42.77-7.67-61.65-22.8z'/%3e%3cpath fill='%23000000' d='M467.2 356c-12.49 0-24.48 13.26-42.76 35.09-22.71 27.14-51 60.91-98 60.91-22.32 0-43.31-7.73-62.4-23-14.34-11.45-25.58-25.21-36.46-38.53C208.37 367 198 356 185.6 356H0v59c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97v-59h-44.8z'/%3e%3c/svg%3e");
|
||||
$bg-icon-session: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M317.8 262.2c3.3 2.1 6.6 4.3 9.6 6.8l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l67.6-54c.1-2.4.1-4.7.1-7.1 0-26.1-3.9-51.2-11.1-74.9L423.5 243c-29.1 23.3-70.1 29.6-105.7 19.2zM124.3 317.1l60.2-48.2c29-23.2 70-29.6 105.6-19.2-3.3-2.1-6.6-4.3-9.6-6.8l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L103.5 243c-20 16-45.7 24-71.5 24-10.8 0-21.5-1.4-31.9-4.2v.8c2.5 1.7 5 3.4 7.3 5.3l60.2 48.2c14.9 11.9 41.9 11.9 56.7 0z'/%3e%3cpath fill='%23000000' d='M60.3 189.1l60.2-48.2c40.1-32.1 102.8-32.1 142.9 0l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l90.5-72.4C425.2 46.5 346 0 256 0 136.7 0 36.4 81.6 8 192.1c15.4 8.8 38.9 7.8 52.3-3zM344.5 371l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L167.5 371c-20 16-45.7 24-71.5 24-23.9 0-47.7-6.9-67.1-20.7C71.7 456.1 157.3 512 256 512s184.3-55.9 227.1-137.7c-40.2 28.7-99.9 27.6-138.6-3.3z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zM320 224H192v-96h128v96zm-128 32h128v96H192v-96zm-32 96H32v-96h128v96zm0-224v96H32v-96h128zM64 480c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h128v96H64zm128 0v-96h128v96H192zm288-32c0 8.5-3.3 16.5-9.4 22.6S456.5 480 448 480h-96v-96h128v64zm0-96H352v-96h128v96zm0-128H352v-96h128v96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-lad: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.7.1.1 28.7 0 64v384c.1 35.3 28.7 63.9 64 64h384c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM32 128h128v96H32v-96zm0 128h128v96H32v-96zm32 224c-17.6-.1-31.9-14.4-32-32v-64h128v96H64zm128 0v-96h128v96H192zm288-32c-.1 17.6-14.4 31.9-32 32h-96v-96h128v64zm0-192v96H192v-96h32v-32h-32v-96h288v96h-32v32h32z'/%3e%3cpath fill='%23000000' d='M391.2 273.7L336 246.1V160c0-8.8-7.2-16-16-16s-16 7.2-16 16v105.9l72.8 36.4c7.9 4 17.5.8 21.5-7.2 4-7.8.8-17.5-7.1-21.4z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-lad-set: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M64 384V96c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64H128c-35.3-.1-63.9-28.7-64-64z'/%3e%3cpath fill='%23000000' d='M448 0H160c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM128 96h96v64h-96V96zm0 96h96v96h-96v-96zm32 192c-17.6-.1-31.9-14.4-32-32v-32h96v64h-64zm96 0v-64h96v64h-96zm224-32c-.1 17.6-14.4 31.9-32 32h-64v-64h96v32zm0-64H256V96h224v192z'/%3e%3cpath fill='%23000000' d='M416 240c8.8 0 16-7.2 16-16 0-6.9-4.4-13-10.9-15.2L384 196.5V144c0-8.8-7.2-16-16-16s-16 7.2-16 16v75.5l58.9 19.6c1.7.6 3.4.9 5.1.9z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabular-scrolling: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M32 0C14.4 0 0 14.4 0 32v96h224V0H32zM512 128V32c0-17.6-14.4-32-32-32H288v128h224zM0 192v96c0 17.6 14.4 32 32 32h192V192H0zM480 320c17.6 0 32-14.4 32-32v-96H288v128h192zM256 512L128 384h256z'/%3e%3c/svg%3e");
|
||||
$bg-icon-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M16 315.83c7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73 18.7-47.75 49.57-103.57 94.47-116.23A255.87 255.87 0 0 0 256 0C114.62 0 0 114.62 0 256a257.18 257.18 0 0 0 5 50.52c4.77 5.39 8.61 8.37 11 9.31z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73-18.7 47.75-49.57 103.57-94.47 116.23A255.87 255.87 0 0 0 256 512c141.38 0 256-114.62 256-256a257.18 257.18 0 0 0-5-50.52c-4.77-5.39-8.61-8.37-11-9.31z'/%3e%3c/svg%3e");
|
||||
$bg-icon-timeline: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M416 0H96C43.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 160V96h128v64Zm64 64h192v64H128Zm320 192H224v-64h224Zm0-128h-64v-64h64Zm0-128H256V96h192Z'/%3e%3c/svg%3e");
|
||||
$bg-icon-timer: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M32 0C14.4 0 0 14.4 0 32v96h224V0H32zM512 128V32c0-17.6-14.4-32-32-32H288v128h224zM0 192v96c0 17.6 14.4 32 32 32h192V192H0zM480 320c17.6 0 32-14.4 32-32v-96H288v128h192zM256 512L128 384h256z'/%3e%3c/svg%3e");
|
||||
$bg-icon-topic: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M16 315.83c7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73 18.7-47.75 49.57-103.57 94.47-116.23A255.87 255.87 0 0 0 256 0C114.62 0 0 114.62 0 256a257.18 257.18 0 0 0 5 50.52c4.77 5.39 8.61 8.37 11 9.31z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73-18.7 47.75-49.57 103.57-94.47 116.23A255.87 255.87 0 0 0 256 512c141.38 0 256-114.62 256-256a257.18 257.18 0 0 0-5-50.52c-4.77-5.39-8.61-8.37-11-9.31z'/%3e%3c/svg%3e");
|
||||
$bg-icon-timer: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M288 73.3V32.01a32 32 0 0 0-32-32h-64a32 32 0 0 0-32 32V73.3C67.48 100.84 0 186.54 0 288.01c0 123.71 100.29 224 224 224s224-100.29 224-224c0-101.48-67.5-187.2-160-214.71zm-54 224.71l-131.88 105.5A167.4 167.4 0 0 1 56 288.01c0-92.64 75.36-168 168-168 3.36 0 6.69.11 10 .31v177.69z'/%3e%3c/svg%3e");
|
||||
$bg-icon-box-with-dashed-lines: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M0 192h64v128H0zM64 64.11l.11-.11H160V0H64A64.19 64.19 0 0 0 0 64v96h64V64.11zM64 447.89V352H0v96a64.19 64.19 0 0 0 64 64h96v-64H64.11zM192 0h128v64H192zM448 447.89l-.11.11H352v64h96a64.19 64.19 0 0 0 64-64v-96h-64v95.89zM448 0h-96v64h95.89l.11.11V160h64V64a64.19 64.19 0 0 0-64-64zM448 192h64v128h-64zM192 448h128v64H192zM128 128h256v256H128z'/%3e%3c/svg%3e");
|
||||
$bg-icon-summary-widget: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M128 128h192v64H128zM192 224h192v64H192zM160 320h192v64H160z'/%3e%3cpath fill='%23000000' d='M416 0h-64v96h63.8c.1 0 .1.1.2.2v319.7c0 .1-.1.1-.2.2H352v96h64c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96zM96 415.8V96.2c0-.1.1-.1.2-.2H160V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h64v-96H96.2c-.1 0-.2-.1-.2-.2z'/%3e%3c/svg%3e");
|
||||
$bg-icon-notebook: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M288 73.3V32.01a32 32 0 0 0-32-32h-64a32 32 0 0 0-32 32V73.3C67.48 100.84 0 186.54 0 288.01c0 123.71 100.29 224 224 224s224-100.29 224-224c0-101.48-67.5-187.2-160-214.71zm-54 224.71l-131.88 105.5A167.4 167.4 0 0 1 56 288.01c0-92.64 75.36-168 168-168 3.36 0 6.69.11 10 .31v177.69z'/%3e%3c/svg%3e");
|
||||
$bg-icon-summary-widget: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M416 0H96C43.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-96zM256 384L64 256l192-128 192 128z'/%3e%3c/svg%3e");
|
||||
$bg-icon-notebook: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512' xml:space='preserve'%3e%3cpath d='M448 55.4c0-39.9-27.7-63.7-61.5-52.7L0 128h448V55.4zM448 160H0v288c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64zm-32 256H224V256h192v160z'/%3e%3c/svg%3e");
|
||||
$bg-icon-tabs-view: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M0 448a64.2 64.2 0 0 0 64 64h384a64.2 64.2 0 0 0 64-64V144H256L230.9 31.2C227.1 14.1 209.6 0 192 0H64A64.2 64.2 0 0 0 0 64zm416-64H96V256h320z'/%3e%3cpath d='M240 0c17.6 0 35.1 14.1 38.9 31.2l18 80.8H512V64a64.2 64.2 0 0 0-64-64z'/%3e%3c/svg%3e");
|
||||
$bg-icon-flexible-layout: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M0 416c0 52.8 43.2 96 96 96h32V224H0zM0 96v64h128V0H96C43.2 0 0 43.2 0 96zM384 512h32c52.8 0 96-43.2 96-96v-64H384zM192 0h128v512H192zM416 0h-32v288h128V96c0-52.8-43.2-96-96-96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-generator-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M76 236.9c5.4-2.1 20.4-17.8 34.9-54.7C126.8 141.5 154.5 93 196 93c19.7 0 38 10.9 54.6 32.5 14 18.2 24.4 40.8 30.5 56.7 14.5 36.9 29.5 52.6 34.9 54.7 5.4-2.1 20.4-17.8 34.9-54.7S388 104.5 421.7 95A192 192 0 0 0 256 0C150 0 64 86 64 192a197.2 197.2 0 0 0 3.7 37.9c3.6 4 6.5 6.3 8.3 7zM442.3 238.5A192.9 192.9 0 0 0 448 192a197.2 197.2 0 0 0-3.7-37.9c-3.6-4-6.5-6.3-8.3-7-5.4 2.1-20.4 17.8-34.9 54.7-10.9 27.9-27.3 59.5-50 76.6z'/%3e%3cpath d='M256 320l67.5-29.5a60.3 60.3 0 0 1-7.5.5c-19.7 0-38-10.9-54.6-32.5-14-18.2-24.4-40.8-30.5-56.7-14.5-36.9-29.5-52.6-34.9-54.7-5.4 2.1-20.4 17.8-34.9 54.7-8.2 21.1-19.6 44.2-34.4 61.6z'/%3e%3cpath d='M512 240L256 352 0 240v160l256 112 256-112V240z'/%3e%3c/svg%3e");
|
||||
@ -325,5 +323,5 @@ $bg-icon-bar-chart: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://w
|
||||
$bg-icon-map: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 32.7 384 64v448l64-31.3c35.2-17.21 64-60.1 64-95.3v-320c0-35.2-28.8-49.91-64-32.7ZM160 456l193.6 48.4v-448L160 8v448zM129.6.4 128 0 64 31.3C28.8 48.51 0 91.4 0 126.6v320c0 35.2 28.8 49.91 64 32.7l64-31.3 1.6.4Z'/%3e%3c/svg%3e");
|
||||
$bg-icon-plan: 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 1'%3e%3cpath fill='%23000000' d='M128 96V64a64.19 64.19 0 0 1 64-64h128a64.19 64.19 0 0 1 64 64v32Z'/%3e%3cpath fill='%23000000' d='M416 64v64H96V64c-52.8 0-96 43.2-96 96v256c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V160c0-52.8-43.2-96-96-96ZM64 288v-64h128v64Zm256 128H128v-64h192Zm128 0h-64v-64h64Zm0-128H256v-64h192Z'/%3e%3c/g%3e%3c/g%3e%3c/svg%3e");
|
||||
$bg-icon-timelist: 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='M448 0H64A64.19 64.19 0 0 0 0 64v384a64.19 64.19 0 0 0 64 64h384a64.19 64.19 0 0 0 64-64V64a64.19 64.19 0 0 0-64-64ZM213.47 266.73a24 24 0 0 1-32.2 10.74L104 238.83V128a24 24 0 0 1 48 0v81.17l50.73 25.36a24 24 0 0 1 10.74 32.2ZM448 448H288v-64h160Zm0-96H288v-64h160Zm0-96H288v-64h160Zm0-96H288V96h160Z' 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-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");
|
||||
|
@ -241,12 +241,10 @@
|
||||
.bg-icon-tabular { @include glyphBg($bg-icon-tabular); }
|
||||
.bg-icon-tabular-lad { @include glyphBg($bg-icon-tabular-lad); }
|
||||
.bg-icon-tabular-lad-set { @include glyphBg($bg-icon-tabular-lad-set); }
|
||||
.bg-icon-tabular-realtime { @include glyphBg($bg-icon-tabular-realtime); }
|
||||
.bg-icon-tabular-scrolling { @include glyphBg($bg-icon-tabular-scrolling); }
|
||||
.bg-icon-telemetry { @include glyphBg($bg-icon-telemetry); }
|
||||
.bg-icon-timeline { @include glyphBg($bg-icon-timeline); }
|
||||
.bg-icon-timer { @include glyphBg($bg-icon-timer); }
|
||||
.bg-icon-topic { @include glyphBg($bg-icon-topic); }
|
||||
.bg-icon-box-with-dashed-lines { @include glyphBg($bg-icon-box-with-dashed-lines); }
|
||||
.bg-icon-summary-widget { @include glyphBg($bg-icon-summary-widget); }
|
||||
.bg-icon-notebook { @include glyphBg($bg-icon-notebook); }
|
||||
@ -264,5 +262,5 @@
|
||||
.bg-icon-map { @include glyphBg($bg-icon-map); }
|
||||
.bg-icon-plan { @include glyphBg($bg-icon-plan); }
|
||||
.bg-icon-timelist { @include glyphBg($bg-icon-timelist); }
|
||||
.bg-icon-notebook-shift-log { @include glyphBg($bg-icon-notebook-shift-log); }
|
||||
.bg-icon-plot-scatter { @include glyphBg($bg-icon-plot-scatter); }
|
||||
.bg-icon-notebook-shift-log { @include glyphBg($bg-icon-notebook-shift-log); }
|
||||
|
@ -54,6 +54,9 @@ const config = {
|
||||
"utils": path.join(__dirname, "src/utils")
|
||||
}
|
||||
},
|
||||
optimization: {
|
||||
minimize: false
|
||||
},
|
||||
plugins: [
|
||||
new webpack.DefinePlugin({
|
||||
__OPENMCT_VERSION__: `'${packageDefinition.version}'`,
|
||||
|
Reference in New Issue
Block a user