Compare commits
38 Commits
large-valu
...
test-mct-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
855918408e | ||
|
|
b0ca16fc14 | ||
|
|
e92b8f9720 | ||
|
|
fdae0ceb72 | ||
|
|
eeff0a7bff | ||
|
|
23a0ddb97c | ||
|
|
724ec423d1 | ||
|
|
b41c98d4ab | ||
|
|
76c37ff410 | ||
|
|
c1d1b03b23 | ||
|
|
e0fc2ae043 | ||
|
|
9a946bcd6f | ||
|
|
9f77c03ddb | ||
|
|
bdf8601091 | ||
|
|
2719a283d2 | ||
|
|
a1d9842c16 | ||
|
|
c77bbc16eb | ||
|
|
05a1d53b92 | ||
|
|
cb93d17742 | ||
|
|
771158de3b | ||
|
|
8d5219cf09 | ||
|
|
625bdc0ed8 | ||
|
|
43fa10443d | ||
|
|
dc0f461d9f | ||
|
|
99cb90987a | ||
|
|
7db9805976 | ||
|
|
f48afeb179 | ||
|
|
e94cf27c9a | ||
|
|
6d68512d99 | ||
|
|
c6ff7f2958 | ||
|
|
3dab216d2c | ||
|
|
2d16e91704 | ||
|
|
c400c7c12d | ||
|
|
9b4410d540 | ||
|
|
6769fb4e3e | ||
|
|
34229d3a86 | ||
|
|
f9c5e12a59 | ||
|
|
72c432ffcc |
@@ -314,15 +314,13 @@ async function _isInEditMode(page, identifier) {
|
||||
*/
|
||||
async function setTimeConductorMode(page, isFixedTimespan = true) {
|
||||
// Click 'mode' button
|
||||
const timeConductorMode = await page.locator('.c-compact-tc');
|
||||
await timeConductorMode.click();
|
||||
await timeConductorMode.locator('.js-mode-button').click();
|
||||
|
||||
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();
|
||||
await page.getByRole('button', { name: 'Time Conductor Mode Menu' }).click();
|
||||
// Switch time conductor mode
|
||||
if (isFixedTimespan) {
|
||||
await page.locator('data-testid=conductor-modeOption-fixed').click();
|
||||
await page.getByRole('menuitem', { name: /Fixed Timespan/ }).click();
|
||||
} else {
|
||||
await page.locator('data-testid=conductor-modeOption-realtime').click();
|
||||
await page.getByRole('menuitem', { name: /Real-Time/ }).click();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,9 +342,12 @@ async function setRealTimeMode(page) {
|
||||
|
||||
/**
|
||||
* @typedef {Object} OffsetValues
|
||||
* @property {string | undefined} hours
|
||||
* @property {string | undefined} mins
|
||||
* @property {string | undefined} secs
|
||||
* @property {string | undefined} startHours
|
||||
* @property {string | undefined} startMins
|
||||
* @property {string | undefined} startSecs
|
||||
* @property {string | undefined} endHours
|
||||
* @property {string | undefined} endMins
|
||||
* @property {string | undefined} endSecs
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -355,19 +356,32 @@ async function setRealTimeMode(page) {
|
||||
* @param {OffsetValues} offset
|
||||
* @param {import('@playwright/test').Locator} offsetButton
|
||||
*/
|
||||
async function setTimeConductorOffset(page, { hours, mins, secs }) {
|
||||
// await offsetButton.click();
|
||||
|
||||
if (hours) {
|
||||
await page.fill('.pr-time-input__hrs', hours);
|
||||
async function setTimeConductorOffset(
|
||||
page,
|
||||
{ startHours, startMins, startSecs, endHours, endMins, endSecs }
|
||||
) {
|
||||
if (startHours) {
|
||||
await page.getByRole('spinbutton', { name: 'Start offset hours' }).fill(startHours);
|
||||
}
|
||||
|
||||
if (mins) {
|
||||
await page.fill('.pr-time-input__mins', mins);
|
||||
if (startMins) {
|
||||
await page.getByRole('spinbutton', { name: 'Start offset minutes' }).fill(startMins);
|
||||
}
|
||||
|
||||
if (secs) {
|
||||
await page.fill('.pr-time-input__secs', secs);
|
||||
if (startSecs) {
|
||||
await page.getByRole('spinbutton', { name: 'Start offset seconds' }).fill(startSecs);
|
||||
}
|
||||
|
||||
if (endHours) {
|
||||
await page.getByRole('spinbutton', { name: 'End offset hours' }).fill(endHours);
|
||||
}
|
||||
|
||||
if (endMins) {
|
||||
await page.getByRole('spinbutton', { name: 'End offset minutes' }).fill(endMins);
|
||||
}
|
||||
|
||||
if (endSecs) {
|
||||
await page.getByRole('spinbutton', { name: 'End offset seconds' }).fill(endSecs);
|
||||
}
|
||||
|
||||
// Click the check button
|
||||
@@ -381,9 +395,8 @@ async function setTimeConductorOffset(page, { hours, mins, secs }) {
|
||||
*/
|
||||
async function setStartOffset(page, offset) {
|
||||
// Click 'mode' button
|
||||
const timeConductorMode = await page.locator('.c-compact-tc');
|
||||
await timeConductorMode.click();
|
||||
await setTimeConductorOffset(page, offset);
|
||||
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();
|
||||
await setTimeConductorOffset(page, offset, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -393,9 +406,51 @@ async function setStartOffset(page, offset) {
|
||||
*/
|
||||
async function setEndOffset(page, offset) {
|
||||
// Click 'mode' button
|
||||
const timeConductorMode = await page.locator('.c-compact-tc');
|
||||
await timeConductorMode.click();
|
||||
await setTimeConductorOffset(page, offset);
|
||||
await page.getByRole('button', { name: 'Time Conductor Mode', exact: true }).click();
|
||||
await setTimeConductorOffset(page, offset, true);
|
||||
}
|
||||
|
||||
async function setTimeConductorBounds(page, startDate, endDate) {
|
||||
// Bring up the time conductor popup
|
||||
await page.click('.l-shell__time-conductor.c-compact-tc');
|
||||
|
||||
await setTimeBounds(page, startDate, endDate);
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
}
|
||||
|
||||
async function setIndependentTimeConductorBounds(page, startDate, endDate) {
|
||||
// Activate Independent Time Conductor in Fixed Time Mode
|
||||
await page.getByRole('switch').click();
|
||||
|
||||
// Bring up the time conductor popup
|
||||
await page.click('.c-conductor-holder--compact .c-compact-tc');
|
||||
|
||||
await expect(page.locator('.itc-popout')).toBeVisible();
|
||||
|
||||
await setTimeBounds(page, startDate, endDate);
|
||||
|
||||
await page.keyboard.press('Enter');
|
||||
}
|
||||
|
||||
async function setTimeBounds(page, startDate, endDate) {
|
||||
if (startDate) {
|
||||
// Fill start time
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Start date' })
|
||||
.fill(startDate.toString().substring(0, 10));
|
||||
await page
|
||||
.getByRole('textbox', { name: 'Start time' })
|
||||
.fill(startDate.toString().substring(11, 19));
|
||||
}
|
||||
|
||||
if (endDate) {
|
||||
// Fill end time
|
||||
await page.getByRole('textbox', { name: 'End date' }).fill(endDate.toString().substring(0, 10));
|
||||
await page
|
||||
.getByRole('textbox', { name: 'End time' })
|
||||
.fill(endDate.toString().substring(11, 19));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -509,6 +564,8 @@ module.exports = {
|
||||
setRealTimeMode,
|
||||
setStartOffset,
|
||||
setEndOffset,
|
||||
setTimeConductorBounds,
|
||||
setIndependentTimeConductorBounds,
|
||||
selectInspectorTab,
|
||||
waitForPlotsToRender
|
||||
};
|
||||
|
||||
@@ -28,10 +28,10 @@ const { createDomainObjectWithDefaults, createNotification } = require('../../ap
|
||||
const { test, expect } = require('../../pluginFixtures');
|
||||
|
||||
test.describe('Notifications List', () => {
|
||||
test('Notifications can be dismissed individually', async ({ page }) => {
|
||||
test.fixme('Notifications can be dismissed individually', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/6122'
|
||||
description: 'https://github.com/nasa/openmct/issues/6820'
|
||||
});
|
||||
|
||||
// Go to baseURL
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
const { test, expect } = require('../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults, createPlanFromJSON } = require('../../../appActions');
|
||||
const {
|
||||
createDomainObjectWithDefaults,
|
||||
createPlanFromJSON,
|
||||
setIndependentTimeConductorBounds
|
||||
} = require('../../../appActions');
|
||||
|
||||
const testPlan = {
|
||||
TEST_GROUP: [
|
||||
@@ -78,9 +82,6 @@ test.describe('Time Strip', () => {
|
||||
});
|
||||
|
||||
// Constant locators
|
||||
const independentTimeConductorInputs = page.locator(
|
||||
'.l-shell__main-independent-time-conductor .c-input--datetime'
|
||||
);
|
||||
const activityBounds = page.locator('.activity-bounds');
|
||||
|
||||
// Goto baseURL
|
||||
@@ -122,9 +123,7 @@ test.describe('Time Strip', () => {
|
||||
});
|
||||
|
||||
await test.step('TimeStrip can use the Independent Time Conductor', async () => {
|
||||
// Activate Independent Time Conductor in Fixed Time Mode
|
||||
await page.click('.c-toggle-switch__slider');
|
||||
expect(await activityBounds.count()).toEqual(0);
|
||||
expect(await activityBounds.count()).toEqual(5);
|
||||
|
||||
// Set the independent time bounds so that only one event is shown
|
||||
const startBound = testPlan.TEST_GROUP[0].start;
|
||||
@@ -132,12 +131,7 @@ test.describe('Time Strip', () => {
|
||||
const startBoundString = new Date(startBound).toISOString().replace('T', ' ');
|
||||
const endBoundString = new Date(endBound).toISOString().replace('T', ' ');
|
||||
|
||||
await independentTimeConductorInputs.nth(0).fill('');
|
||||
await independentTimeConductorInputs.nth(0).fill(startBoundString);
|
||||
await page.keyboard.press('Enter');
|
||||
await independentTimeConductorInputs.nth(1).fill('');
|
||||
await independentTimeConductorInputs.nth(1).fill(endBoundString);
|
||||
await page.keyboard.press('Enter');
|
||||
await setIndependentTimeConductorBounds(page, startBoundString, endBoundString);
|
||||
expect(await activityBounds.count()).toEqual(1);
|
||||
});
|
||||
|
||||
@@ -156,9 +150,6 @@ test.describe('Time Strip', () => {
|
||||
await page.click("button[title='Save']");
|
||||
await page.click("li[title='Save and Finish Editing']");
|
||||
|
||||
// Activate Independent Time Conductor in Fixed Time Mode
|
||||
await page.click('.c-toggle-switch__slider');
|
||||
|
||||
// All events should be displayed at this point because the
|
||||
// initial independent context bounds will match the global bounds
|
||||
expect(await activityBounds.count()).toEqual(5);
|
||||
@@ -169,12 +160,7 @@ test.describe('Time Strip', () => {
|
||||
const startBoundString = new Date(startBound).toISOString().replace('T', ' ');
|
||||
const endBoundString = new Date(endBound).toISOString().replace('T', ' ');
|
||||
|
||||
await independentTimeConductorInputs.nth(0).fill('');
|
||||
await independentTimeConductorInputs.nth(0).fill(startBoundString);
|
||||
await page.keyboard.press('Enter');
|
||||
await independentTimeConductorInputs.nth(1).fill('');
|
||||
await independentTimeConductorInputs.nth(1).fill(endBoundString);
|
||||
await page.keyboard.press('Enter');
|
||||
await setIndependentTimeConductorBounds(page, startBoundString, endBoundString);
|
||||
|
||||
// Verify that two events are displayed
|
||||
expect(await activityBounds.count()).toEqual(2);
|
||||
|
||||
@@ -41,7 +41,7 @@ test.describe('Clock Generator CRUD Operations', () => {
|
||||
await page.click('button:has-text("Create")');
|
||||
|
||||
// Click Clock
|
||||
await page.click('text=Clock');
|
||||
await page.getByRole('menuitem').first().click();
|
||||
|
||||
// Click .icon-arrow-down
|
||||
await page.locator('.icon-arrow-down').click();
|
||||
|
||||
@@ -25,7 +25,8 @@ const {
|
||||
createDomainObjectWithDefaults,
|
||||
setStartOffset,
|
||||
setFixedTimeMode,
|
||||
setRealTimeMode
|
||||
setRealTimeMode,
|
||||
setIndependentTimeConductorBounds
|
||||
} = require('../../../../appActions');
|
||||
|
||||
test.describe('Display Layout', () => {
|
||||
@@ -231,20 +232,27 @@ test.describe('Display Layout', () => {
|
||||
let layoutGridHolder = page.locator('.l-layout__grid-holder');
|
||||
await exampleImageryTreeItem.dragTo(layoutGridHolder);
|
||||
|
||||
//adjust so that we can see the independent time conductor toggle
|
||||
// Adjust object height
|
||||
await page.locator('div[title="Resize object height"] > input').click();
|
||||
await page.locator('div[title="Resize object height"] > input').fill('70');
|
||||
|
||||
// Adjust object width
|
||||
await page.locator('div[title="Resize object width"] > input').click();
|
||||
await page.locator('div[title="Resize object width"] > input').fill('70');
|
||||
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
|
||||
// flip on independent time conductor
|
||||
await page.getByTitle('Enable independent Time Conductor').first().locator('label').click();
|
||||
await page.getByRole('textbox').nth(1).fill('2021-12-30 01:11:00.000Z');
|
||||
await page.getByRole('textbox').nth(0).fill('2021-12-30 01:01:00.000Z');
|
||||
await page.getByRole('textbox').nth(1).click();
|
||||
const startDate = '2021-12-30 01:01:00.000Z';
|
||||
const endDate = '2021-12-30 01:11:00.000Z';
|
||||
await setIndependentTimeConductorBounds(page, startDate, endDate);
|
||||
|
||||
// check image date
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
|
||||
// flip it off
|
||||
await page.getByTitle('Disable independent Time Conductor').first().locator('label').click();
|
||||
await page.getByRole('switch').click();
|
||||
// timestamp shouldn't be in the past anymore
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z')).toBeHidden();
|
||||
});
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
*****************************************************************************/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
const {
|
||||
createDomainObjectWithDefaults,
|
||||
setIndependentTimeConductorBounds
|
||||
} = require('../../../../appActions');
|
||||
|
||||
test.describe('Flexible Layout', () => {
|
||||
let sineWaveObject;
|
||||
@@ -187,16 +190,17 @@ test.describe('Flexible Layout', () => {
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
|
||||
// flip on independent time conductor
|
||||
await page.getByTitle('Enable independent Time Conductor').first().locator('label').click();
|
||||
await page.getByRole('textbox').nth(1).fill('2021-12-30 01:11:00.000Z');
|
||||
await page.getByRole('textbox').nth(0).fill('2021-12-30 01:01:00.000Z');
|
||||
await page.getByRole('textbox').nth(1).click();
|
||||
await setIndependentTimeConductorBounds(
|
||||
page,
|
||||
'2021-12-30 01:01:00.000Z',
|
||||
'2021-12-30 01:11:00.000Z'
|
||||
);
|
||||
|
||||
// check image date
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
|
||||
// flip it off
|
||||
await page.getByTitle('Disable independent Time Conductor').first().locator('label').click();
|
||||
await page.getByRole('switch').click();
|
||||
// timestamp shouldn't be in the past anymore
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z')).toBeHidden();
|
||||
});
|
||||
|
||||
@@ -27,7 +27,7 @@ but only assume that example imagery is present.
|
||||
/* globals process */
|
||||
const { waitForAnimations } = require('../../../../baseFixtures');
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
const { createDomainObjectWithDefaults, setRealTimeMode } = require('../../../../appActions');
|
||||
const backgroundImageSelector = '.c-imagery__main-image__background-image';
|
||||
const panHotkey = process.platform === 'linux' ? ['Shift', 'Alt'] : ['Alt'];
|
||||
const tagHotkey = ['Shift', 'Alt'];
|
||||
@@ -46,6 +46,7 @@ test.describe('Example Imagery Object', () => {
|
||||
// Verify that the created object is focused
|
||||
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
|
||||
await page.locator('.c-imagery__main-image__bg').hover({ trial: true });
|
||||
await page.locator(backgroundImageSelector).waitFor();
|
||||
});
|
||||
|
||||
test('Can use Mouse Wheel to zoom in and out of latest image', async ({ page }) => {
|
||||
@@ -71,46 +72,62 @@ test.describe('Example Imagery Object', () => {
|
||||
});
|
||||
|
||||
test('Can use independent time conductor to change time', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/6821'
|
||||
});
|
||||
// Test independent fixed time with global fixed time
|
||||
// flip on independent time conductor
|
||||
await page.getByTitle('Enable independent Time Conductor').locator('label').click();
|
||||
await page.getByRole('textbox').nth(1).fill('2021-12-30 01:11:00.000Z');
|
||||
await page.getByRole('textbox').nth(0).fill('2021-12-30 01:01:00.000Z');
|
||||
await page.getByRole('textbox').nth(1).click();
|
||||
await page.getByRole('switch', { name: 'Enable Independent Time Conductor' }).click();
|
||||
await page.getByRole('button', { name: 'Independent Time Conductor Settings' }).click();
|
||||
await page.getByRole('textbox', { name: 'Start date' }).click();
|
||||
await page.getByRole('textbox', { name: 'Start date' }).fill('');
|
||||
await page.getByRole('textbox', { name: 'Start date' }).fill('2021-12-30');
|
||||
await page.getByRole('textbox', { name: 'Start time' }).click();
|
||||
await page.getByRole('textbox', { name: 'Start time' }).fill('');
|
||||
await page.getByRole('textbox', { name: 'Start time' }).fill('01:01:00');
|
||||
await page.getByRole('textbox', { name: 'End date' }).click();
|
||||
await page.getByRole('textbox', { name: 'End date' }).fill('');
|
||||
await page.getByRole('textbox', { name: 'End date' }).fill('2021-12-30');
|
||||
await page.getByRole('textbox', { name: 'End time' }).click();
|
||||
await page.getByRole('textbox', { name: 'End time' }).fill('');
|
||||
await page.getByRole('textbox', { name: 'End time' }).fill('01:11:00');
|
||||
await page.getByRole('button', { name: 'Submit time bounds' }).click();
|
||||
|
||||
// check image date
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
|
||||
// flip it off
|
||||
await page.getByTitle('Disable independent Time Conductor').locator('label').click();
|
||||
await page.getByRole('switch', { name: 'Disable Independent Time Conductor' }).click();
|
||||
// timestamp shouldn't be in the past anymore
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z')).toBeHidden();
|
||||
|
||||
// Test independent fixed time with global realtime
|
||||
await page.getByRole('button', { name: /Fixed Timespan/ }).click();
|
||||
await page.getByTestId('conductor-modeOption-realtime').click();
|
||||
await page.getByTitle('Enable independent Time Conductor').locator('label').click();
|
||||
await setRealTimeMode(page);
|
||||
await page.getByRole('switch', { name: 'Enable Independent Time Conductor' }).click();
|
||||
// check image date to be in the past
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
// flip it off
|
||||
await page.getByTitle('Disable independent Time Conductor').locator('label').click();
|
||||
await page.getByRole('switch', { name: 'Disable Independent Time Conductor' }).click();
|
||||
// timestamp shouldn't be in the past anymore
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z')).toBeHidden();
|
||||
|
||||
|
||||
// Test independent realtime with global realtime
|
||||
await page.getByTitle('Enable independent Time Conductor').locator('label').click();
|
||||
await page.getByRole('switch', { name: 'Enable Independent Time Conductor' }).click();
|
||||
// check image date
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
// change independent time to realtime
|
||||
await page.getByRole('button', { name: /Fixed Timespan/ }).click();
|
||||
await page.getByRole('menuitem', { name: /Local Clock/ }).click();
|
||||
await page.getByRole('button', { name: 'Independent Time Conductor Settings' }).click();
|
||||
await page.getByRole('button', { name: "Independent Time Conductor Mode Menu" }).click();
|
||||
await page.getByRole('menuitem', { name: /Real-Time/ }).click();
|
||||
// timestamp shouldn't be in the past anymore
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z')).toBeHidden();
|
||||
// back to the past
|
||||
await page.getByRole('button', { name: "Independent Time Conductor Mode Menu" }).click();
|
||||
await page
|
||||
.getByRole('button', { name: /Local Clock/ })
|
||||
.first()
|
||||
.click();
|
||||
.getByRole('menuitem', { name: /Real-Time/ })
|
||||
.click();
|
||||
await page.getByRole('button', { name: "Independent Time Conductor Mode Menu" }).click();
|
||||
await page.getByRole('menuitem', { name: /Fixed Timespan/ }).click();
|
||||
// check image date to be in the past
|
||||
await expect(page.getByText('2021-12-30 01:11:00.000Z').first()).toBeVisible();
|
||||
@@ -247,7 +264,7 @@ test.describe('Example Imagery Object', () => {
|
||||
|
||||
test('Uses low fetch priority', async ({ page }) => {
|
||||
const priority = await page.locator('.js-imageryView-image').getAttribute('fetchpriority');
|
||||
await expect(priority).toBe('low');
|
||||
expect(priority).toBe('low');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -281,7 +298,7 @@ test.describe('Example Imagery in Display Layout', () => {
|
||||
await setRealTimeMode(page);
|
||||
|
||||
// pause/play button
|
||||
const pausePlayButton = await page.locator('.c-button.pause-play');
|
||||
const pausePlayButton = page.locator('.c-button.pause-play');
|
||||
|
||||
await expect.soft(pausePlayButton).not.toHaveClass(/is-paused/);
|
||||
|
||||
@@ -304,7 +321,7 @@ test.describe('Example Imagery in Display Layout', () => {
|
||||
await setRealTimeMode(page);
|
||||
|
||||
// pause/play button
|
||||
const pausePlayButton = await page.locator('.c-button.pause-play');
|
||||
const pausePlayButton = page.locator('.c-button.pause-play');
|
||||
await pausePlayButton.click();
|
||||
await expect.soft(pausePlayButton).toHaveClass(/is-paused/);
|
||||
|
||||
@@ -928,15 +945,3 @@ async function createImageryView(page) {
|
||||
page.waitForSelector('.c-message-banner__message')
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('@playwright/test').Page} page
|
||||
*/
|
||||
async function setRealTimeMode(page) {
|
||||
await page.locator('.c-compact-tc').click();
|
||||
await page.waitForSelector('.c-tc-input-popup', { state: 'visible' });
|
||||
// Click mode dropdown
|
||||
await page.getByRole('button', { name: ' Fixed Timespan ' }).click();
|
||||
// Click realtime
|
||||
await page.getByTestId('conductor-modeOption-realtime').click();
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ test.describe('Restricted Notebook with at least one entry and with the page loc
|
||||
// Click the context menu button for the new page
|
||||
await page.getByTitle('Open context menu').click();
|
||||
// Delete the page
|
||||
await page.getByRole('listitem', { name: 'Delete Page' }).click();
|
||||
await page.getByRole('menuitem', { name: 'Delete Page' }).click();
|
||||
// Click OK button
|
||||
await page.getByRole('button', { name: 'Ok' }).click();
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
Testsuite for plot autoscale.
|
||||
*/
|
||||
|
||||
const { selectInspectorTab } = require('../../../../appActions');
|
||||
const { selectInspectorTab, setTimeConductorBounds } = require('../../../../appActions');
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
test.use({
|
||||
viewport: {
|
||||
@@ -131,12 +131,7 @@ async function setTimeRange(
|
||||
// Set a specific time range for consistency, otherwise it will change
|
||||
// on every test to a range based on the current time.
|
||||
|
||||
const timeInputs = page.locator('input.c-input--datetime');
|
||||
await timeInputs.first().click();
|
||||
await timeInputs.first().fill(start);
|
||||
|
||||
await timeInputs.nth(1).click();
|
||||
await timeInputs.nth(1).fill(end);
|
||||
await setTimeConductorBounds(page, start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
@@ -26,7 +26,7 @@ necessarily be used for reference when writing new tests in this area.
|
||||
*/
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const { selectInspectorTab } = require('../../../../appActions');
|
||||
const { selectInspectorTab, setTimeConductorBounds } = require('../../../../appActions');
|
||||
|
||||
test.describe('Log plot tests', () => {
|
||||
test('Log Plot ticks are functionally correct in regular and log mode and after refresh', async ({
|
||||
@@ -87,12 +87,10 @@ async function makeOverlayPlot(page, myItemsFolderName) {
|
||||
// Set a specific time range for consistency, otherwise it will change
|
||||
// on every test to a range based on the current time.
|
||||
|
||||
const timeInputs = page.locator('input.c-input--datetime');
|
||||
await timeInputs.first().click();
|
||||
await timeInputs.first().fill('2022-03-29 22:00:00.000Z');
|
||||
const start = '2022-03-29 22:00:00.000Z';
|
||||
const end = '2022-03-29 22:00:30.000Z';
|
||||
|
||||
await timeInputs.nth(1).click();
|
||||
await timeInputs.nth(1).fill('2022-03-29 22:00:30.000Z');
|
||||
await setTimeConductorBounds(page, start, end);
|
||||
|
||||
// create overlay plot
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ const {
|
||||
waitForPlotsToRender
|
||||
} = require('../../../../appActions');
|
||||
|
||||
test.describe('Plot Tagging', () => {
|
||||
test.describe.fixme('Plot Tagging', () => {
|
||||
/**
|
||||
* Given a canvas and a set of points, tags the points on the canvas.
|
||||
* @param {import('@playwright/test').Page} page
|
||||
@@ -167,6 +167,10 @@ test.describe('Plot Tagging', () => {
|
||||
});
|
||||
|
||||
test('Tags work with Overlay Plots', async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/6822'
|
||||
});
|
||||
//Test.slow decorator is currently broken. Needs to be fixed in https://github.com/nasa/openmct/issues/5374
|
||||
test.slow();
|
||||
|
||||
|
||||
@@ -20,7 +20,10 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||
const {
|
||||
createDomainObjectWithDefaults,
|
||||
setTimeConductorBounds
|
||||
} = require('../../../../appActions');
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
|
||||
test.describe('Telemetry Table', () => {
|
||||
@@ -51,18 +54,14 @@ test.describe('Telemetry Table', () => {
|
||||
await expect(tableWrapper).toHaveClass(/is-paused/);
|
||||
|
||||
// Subtract 5 minutes from the current end bound datetime and set it
|
||||
const endTimeInput = page.locator('input[type="text"].c-input--datetime').nth(1);
|
||||
await endTimeInput.click();
|
||||
|
||||
let endDate = await endTimeInput.inputValue();
|
||||
// Bring up the time conductor popup
|
||||
let endDate = await page.locator('[aria-label="End bounds"]').textContent();
|
||||
endDate = new Date(endDate);
|
||||
|
||||
endDate.setUTCMinutes(endDate.getUTCMinutes() - 5);
|
||||
endDate = endDate.toISOString().replace(/T/, ' ');
|
||||
|
||||
await endTimeInput.fill('');
|
||||
await endTimeInput.fill(endDate);
|
||||
await page.keyboard.press('Enter');
|
||||
await setTimeConductorBounds(page, undefined, endDate);
|
||||
|
||||
await expect(tableWrapper).not.toHaveClass(/is-paused/);
|
||||
|
||||
|
||||
@@ -25,7 +25,8 @@ const {
|
||||
setFixedTimeMode,
|
||||
setRealTimeMode,
|
||||
setStartOffset,
|
||||
setEndOffset
|
||||
setEndOffset,
|
||||
setTimeConductorBounds
|
||||
} = require('../../../../appActions');
|
||||
|
||||
test.describe('Time conductor operations', () => {
|
||||
@@ -40,38 +41,36 @@ test.describe('Time conductor operations', () => {
|
||||
let endDate = 'xxxx-01-01 02:00:00.000Z';
|
||||
endDate = year + endDate.substring(4);
|
||||
|
||||
const startTimeLocator = page.locator('input[type="text"]').first();
|
||||
const endTimeLocator = page.locator('input[type="text"]').nth(1);
|
||||
|
||||
// Click start time
|
||||
await startTimeLocator.click();
|
||||
|
||||
// Click end time
|
||||
await endTimeLocator.click();
|
||||
|
||||
await endTimeLocator.fill(endDate.toString());
|
||||
await startTimeLocator.fill(startDate.toString());
|
||||
await setTimeConductorBounds(page, startDate, endDate);
|
||||
|
||||
// invalid start date
|
||||
startDate = year + 1 + startDate.substring(4);
|
||||
await startTimeLocator.fill(startDate.toString());
|
||||
await endTimeLocator.click();
|
||||
await setTimeConductorBounds(page, startDate);
|
||||
|
||||
const startDateValidityStatus = await startTimeLocator.evaluate((element) =>
|
||||
// Bring up the time conductor popup
|
||||
const timeConductorMode = await page.locator('.c-compact-tc');
|
||||
await timeConductorMode.click();
|
||||
const startDateLocator = page.locator('input[type="text"]').first();
|
||||
const endDateLocator = page.locator('input[type="text"]').nth(2);
|
||||
|
||||
await endDateLocator.click();
|
||||
|
||||
const startDateValidityStatus = await startDateLocator.evaluate((element) =>
|
||||
element.checkValidity()
|
||||
);
|
||||
expect(startDateValidityStatus).not.toBeTruthy();
|
||||
|
||||
// fix to valid start date
|
||||
startDate = year - 1 + startDate.substring(4);
|
||||
await startTimeLocator.fill(startDate.toString());
|
||||
await setTimeConductorBounds(page, startDate);
|
||||
|
||||
// invalid end date
|
||||
endDate = year - 2 + endDate.substring(4);
|
||||
await endTimeLocator.fill(endDate.toString());
|
||||
await startTimeLocator.click();
|
||||
await setTimeConductorBounds(page, undefined, endDate);
|
||||
|
||||
const endDateValidityStatus = await endTimeLocator.evaluate((element) =>
|
||||
await startDateLocator.click();
|
||||
|
||||
const endDateValidityStatus = await endDateLocator.evaluate((element) =>
|
||||
element.checkValidity()
|
||||
);
|
||||
expect(endDateValidityStatus).not.toBeTruthy();
|
||||
@@ -83,11 +82,11 @@ test.describe('Time conductor operations', () => {
|
||||
test.describe('Time conductor input fields real-time mode', () => {
|
||||
test('validate input fields in real-time mode', async ({ page }) => {
|
||||
const startOffset = {
|
||||
secs: '23'
|
||||
startSecs: '23'
|
||||
};
|
||||
|
||||
const endOffset = {
|
||||
secs: '31'
|
||||
endSecs: '31'
|
||||
};
|
||||
|
||||
// Go to baseURL
|
||||
@@ -100,15 +99,13 @@ test.describe('Time conductor input fields real-time mode', () => {
|
||||
await setStartOffset(page, startOffset);
|
||||
|
||||
// Verify time was updated on time offset button
|
||||
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText(
|
||||
'00:30:23'
|
||||
);
|
||||
await expect(page.locator('.c-compact-tc__setting-value.icon-minus')).toContainText('00:30:23');
|
||||
|
||||
// Set end time offset
|
||||
await setEndOffset(page, endOffset);
|
||||
|
||||
// Verify time was updated on preceding time offset button
|
||||
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:31');
|
||||
await expect(page.locator('.c-compact-tc__setting-value.icon-plus')).toContainText('00:00:31');
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -119,12 +116,12 @@ test.describe('Time conductor input fields real-time mode', () => {
|
||||
page
|
||||
}) => {
|
||||
const startOffset = {
|
||||
mins: '30',
|
||||
secs: '23'
|
||||
startMins: '30',
|
||||
startSecs: '23'
|
||||
};
|
||||
|
||||
const endOffset = {
|
||||
secs: '01'
|
||||
endSecs: '01'
|
||||
};
|
||||
|
||||
// Convert offsets to milliseconds
|
||||
@@ -150,12 +147,10 @@ test.describe('Time conductor input fields real-time mode', () => {
|
||||
await setRealTimeMode(page);
|
||||
|
||||
// Verify updated start time offset persists after mode switch
|
||||
await expect(page.locator('data-testid=conductor-start-offset-button')).toContainText(
|
||||
'00:30:23'
|
||||
);
|
||||
await expect(page.locator('.c-compact-tc__setting-value.icon-minus')).toContainText('00:30:23');
|
||||
|
||||
// Verify updated end time offset persists after mode switch
|
||||
await expect(page.locator('data-testid=conductor-end-offset-button')).toContainText('00:00:01');
|
||||
await expect(page.locator('.c-compact-tc__setting-value.icon-plus')).toContainText('00:00:01');
|
||||
|
||||
// Verify url parameters persist after mode switch
|
||||
await page.waitForNavigation({ waitUntil: 'networkidle' });
|
||||
@@ -203,11 +198,11 @@ test.describe('Time Conductor History', () => {
|
||||
// with startBound at 2022-01-01 00:00:00.000Z
|
||||
// and endBound at 2022-01-01 00:00:00.200Z
|
||||
await page.goto(
|
||||
'./#/browse/mine?view=grid&tc.mode=fixed&tc.startBound=1640995200000&tc.endBound=1640995200200&tc.timeSystem=utc&hideInspector=true',
|
||||
{ waitUntil: 'networkidle' }
|
||||
'./#/browse/mine?view=grid&tc.mode=fixed&tc.startBound=1640995200000&tc.endBound=1640995200200&tc.timeSystem=utc&hideInspector=true'
|
||||
);
|
||||
await page.locator("[aria-label='Time Conductor History']").hover({ trial: true });
|
||||
await page.locator("[aria-label='Time Conductor History']").click();
|
||||
await page.getByRole('button', { name: 'Time Conductor Settings' }).click();
|
||||
await page.getByRole('button', { name: 'Time Conductor History' }).hover({ trial: true });
|
||||
await page.getByRole('button', { name: 'Time Conductor History' }).click();
|
||||
|
||||
// Validate history item format
|
||||
const historyItem = page.locator('text="2022-01-01 00:00:00 + 200ms"');
|
||||
|
||||
@@ -59,53 +59,60 @@ test.describe('Recent Objects', () => {
|
||||
await page.mouse.move(0, 100);
|
||||
await page.mouse.up();
|
||||
});
|
||||
test('Navigated objects show up in recents, object renames and deletions are reflected', async ({
|
||||
page
|
||||
}) => {
|
||||
// Verify that both created objects appear in the list and are in the correct order
|
||||
await assertInitialRecentObjectsListState();
|
||||
|
||||
// Navigate to the folder by clicking on the main object name in the recent objects list item
|
||||
await page.getByRole('listitem', { name: folderA.name }).getByText(folderA.name).click();
|
||||
await page.waitForURL(`**/${folderA.uuid}?*`);
|
||||
expect(recentObjectsList.getByRole('listitem').nth(0).getByText(folderA.name)).toBeTruthy();
|
||||
|
||||
// Rename
|
||||
folderA.name = `${folderA.name}-NEW!`;
|
||||
await page.locator('.l-browse-bar__object-name').fill('');
|
||||
await page.locator('.l-browse-bar__object-name').fill(folderA.name);
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// Verify rename has been applied in recent objects list item and objects paths
|
||||
expect(
|
||||
await page
|
||||
.getByRole('navigation', {
|
||||
name: clock.name
|
||||
})
|
||||
.locator('a')
|
||||
.filter({
|
||||
hasText: folderA.name
|
||||
})
|
||||
.count()
|
||||
).toBeGreaterThan(0);
|
||||
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeTruthy();
|
||||
|
||||
// Delete
|
||||
await page.click('button[title="Show selected item in tree"]');
|
||||
// Delete the folder via the left tree pane treeitem context menu
|
||||
await page
|
||||
.getByRole('treeitem', { name: new RegExp(folderA.name) })
|
||||
.locator('a')
|
||||
.click({
|
||||
button: 'right'
|
||||
test.fixme(
|
||||
'Navigated objects show up in recents, object renames and deletions are reflected',
|
||||
async ({ page }) => {
|
||||
test.info().annotations.push({
|
||||
type: 'issue',
|
||||
description: 'https://github.com/nasa/openmct/issues/6818'
|
||||
});
|
||||
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
|
||||
// Verify that the folder and clock are no longer in the recent objects list
|
||||
await expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeHidden();
|
||||
await expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeHidden();
|
||||
});
|
||||
// Verify that both created objects appear in the list and are in the correct order
|
||||
await assertInitialRecentObjectsListState();
|
||||
|
||||
// Navigate to the folder by clicking on the main object name in the recent objects list item
|
||||
await page.getByRole('listitem', { name: folderA.name }).getByText(folderA.name).click();
|
||||
await page.waitForURL(`**/${folderA.uuid}?*`);
|
||||
expect(recentObjectsList.getByRole('listitem').nth(0).getByText(folderA.name)).toBeTruthy();
|
||||
|
||||
// Rename
|
||||
folderA.name = `${folderA.name}-NEW!`;
|
||||
await page.locator('.l-browse-bar__object-name').fill('');
|
||||
await page.locator('.l-browse-bar__object-name').fill(folderA.name);
|
||||
await page.keyboard.press('Enter');
|
||||
|
||||
// Verify rename has been applied in recent objects list item and objects paths
|
||||
expect(
|
||||
await page
|
||||
.getByRole('navigation', {
|
||||
name: clock.name
|
||||
})
|
||||
.locator('a')
|
||||
.filter({
|
||||
hasText: folderA.name
|
||||
})
|
||||
.count()
|
||||
).toBeGreaterThan(0);
|
||||
expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeTruthy();
|
||||
|
||||
// Delete
|
||||
await page.click('button[title="Show selected item in tree"]');
|
||||
// Delete the folder via the left tree pane treeitem context menu
|
||||
await page
|
||||
.getByRole('treeitem', { name: new RegExp(folderA.name) })
|
||||
.locator('a')
|
||||
.click({
|
||||
button: 'right'
|
||||
});
|
||||
await page.getByRole('menuitem', { name: /Remove/ }).click();
|
||||
await page.getByRole('button', { name: 'OK' }).click();
|
||||
|
||||
// Verify that the folder and clock are no longer in the recent objects list
|
||||
await expect(recentObjectsList.getByRole('listitem', { name: folderA.name })).toBeHidden();
|
||||
await expect(recentObjectsList.getByRole('listitem', { name: clock.name })).toBeHidden();
|
||||
}
|
||||
);
|
||||
|
||||
test('Clicking on an object in the path of a recent object navigates to the object', async ({
|
||||
page,
|
||||
openmctConfig
|
||||
|
||||
@@ -77,11 +77,11 @@ test.describe('Grand Search', () => {
|
||||
|
||||
// Click [aria-label="OpenMCT Search"] a >> nth=0
|
||||
await page.locator('[aria-label="Search Result"] >> nth=0').click();
|
||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeInViewport();
|
||||
|
||||
// Fill [aria-label="OpenMCT Search"] input[type="search"]
|
||||
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('foo');
|
||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
|
||||
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toBeInViewport();
|
||||
|
||||
// Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1
|
||||
await page
|
||||
|
||||
@@ -98,6 +98,7 @@
|
||||
"test:e2e:updatesnapshots": "npx playwright test --config=e2e/playwright-ci.config.js --project=chrome --grep @snapshot --update-snapshots",
|
||||
"test:e2e:visual": "percy exec --config ./e2e/.percy.yml -- npx playwright test --config=e2e/playwright-visual.config.js --grep-invert @unstable",
|
||||
"test:e2e:full": "npx playwright test --config=e2e/playwright-ci.config.js --grep-invert @couchdb",
|
||||
"test:e2e:watch": "npx playwright test --ui --config=e2e/playwright-ci.config.js",
|
||||
"test:perf": "npx playwright test --config=e2e/playwright-performance.config.js",
|
||||
"update-about-dialog-copyright": "perl -pi -e 's/20\\d\\d\\-202\\d/2014\\-2023/gm' ./src/ui/layout/AboutDialog.vue",
|
||||
"update-copyright-date": "npm run update-about-dialog-copyright && grep -lr --null --include=*.{js,scss,vue,ts,sh,html,md,frag} 'Copyright (c) 20' . | xargs -r0 perl -pi -e 's/Copyright\\s\\(c\\)\\s20\\d\\d\\-20\\d\\d/Copyright \\(c\\)\\ 2014\\-2023/gm'",
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
role="menuitem"
|
||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||
:title="action.description"
|
||||
:data-testid="action.testId || null"
|
||||
@click="action.onItemClicked"
|
||||
>
|
||||
{{ action.name }}
|
||||
@@ -53,7 +52,6 @@
|
||||
role="menuitem"
|
||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||
:title="action.description"
|
||||
:data-testid="action.testId || null"
|
||||
@click="action.onItemClicked"
|
||||
>
|
||||
{{ action.name }}
|
||||
|
||||
@@ -34,7 +34,6 @@
|
||||
role="menuitem"
|
||||
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
|
||||
:title="action.description"
|
||||
:data-testid="action.testId || null"
|
||||
@click="action.onItemClicked"
|
||||
@mouseover="toggleItemDescription(action)"
|
||||
@mouseleave="toggleItemDescription()"
|
||||
@@ -59,7 +58,6 @@
|
||||
role="menuitem"
|
||||
:class="action.cssClass"
|
||||
:title="action.description"
|
||||
:data-testid="action.testId || null"
|
||||
@click="action.onItemClicked"
|
||||
@mouseover="toggleItemDescription(action)"
|
||||
@mouseleave="toggleItemDescription()"
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
v-if="dismissable"
|
||||
aria-label="Close"
|
||||
class="c-click-icon c-overlay__close-button icon-x"
|
||||
@click="destroy"
|
||||
@click.stop="destroy"
|
||||
></button>
|
||||
<div
|
||||
ref="element"
|
||||
@@ -71,16 +71,16 @@ export default {
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
destroy: function () {
|
||||
destroy() {
|
||||
if (this.dismissable) {
|
||||
this.dismiss();
|
||||
}
|
||||
},
|
||||
buttonClickHandler: function (method) {
|
||||
buttonClickHandler(method) {
|
||||
method();
|
||||
this.$emit('destroy');
|
||||
},
|
||||
getElementForFocus: function () {
|
||||
getElementForFocus() {
|
||||
const defaultElement = this.$refs.element;
|
||||
if (!this.$refs.buttons) {
|
||||
return defaultElement;
|
||||
|
||||
@@ -299,6 +299,14 @@ class IndependentTimeContext extends TimeContext {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
isRealTime() {
|
||||
if (this.upstreamTimeContext) {
|
||||
return this.upstreamTimeContext.isRealTime(...arguments);
|
||||
} else {
|
||||
return super.isRealTime(...arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Causes this time context to follow another time context (either the global context, or another upstream time context)
|
||||
* This allows views to have their own time context which points to the appropriate upstream context as necessary, achieving nesting.
|
||||
|
||||
@@ -151,7 +151,7 @@ export default {
|
||||
);
|
||||
const ladTable = this.ladTableObjects[index];
|
||||
|
||||
this.$delete(this.ladTelemetryObjects, ladTable.key);
|
||||
delete this.ladTelemetryObjects[ladTable.key];
|
||||
this.ladTableObjects.splice(index, 1);
|
||||
|
||||
this.shouldShowUnitsCheckbox();
|
||||
@@ -224,7 +224,7 @@ export default {
|
||||
}
|
||||
|
||||
if (!showUnitsCheckbox && this.headers?.units) {
|
||||
this.$delete(this.headers, 'units');
|
||||
delete this.headers.units;
|
||||
}
|
||||
},
|
||||
metadataHasUnits(domainObject) {
|
||||
|
||||
@@ -178,7 +178,7 @@ export default {
|
||||
this.unwatchStaleness(combinedKey);
|
||||
});
|
||||
|
||||
this.$delete(this.ladTelemetryObjects, ladTable.key);
|
||||
delete this.ladTelemetryObjects[ladTable.key];
|
||||
this.ladTableObjects.splice(index, 1);
|
||||
},
|
||||
reorderLadTables(reorderPlan) {
|
||||
|
||||
@@ -200,7 +200,7 @@ export default {
|
||||
this.openmct.objects.areIdsEqual(seriesIdentifier, plotSeries.identifier)
|
||||
);
|
||||
if (index >= 0) {
|
||||
this.$delete(this.plotSeries, index);
|
||||
this.plotSeries.splice(index, 1);
|
||||
this.setupOptions();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -112,7 +112,7 @@ export default {
|
||||
|
||||
const foundSeries = seriesIndex > -1;
|
||||
if (foundSeries) {
|
||||
this.$delete(this.plotSeries, seriesIndex);
|
||||
this.plotSeries.splice(seriesIndex, 1);
|
||||
this.setAxesLabels();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -143,7 +143,7 @@ export default {
|
||||
this.openmct.objects.areIdsEqual(seriesIdentifier, plotSeries.identifier)
|
||||
);
|
||||
if (index >= 0) {
|
||||
this.$delete(this.plotSeries, index);
|
||||
this.plotSeries.splice(index, 1);
|
||||
this.setupOptions();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -162,7 +162,7 @@ export default {
|
||||
showGrid: true,
|
||||
viewContext: {},
|
||||
gridDimensions: [0, 0],
|
||||
layoutItems: this.domainObject.configuration.items
|
||||
layoutItems: this.domainObject.configuration.items || []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -227,7 +227,7 @@ export default {
|
||||
|
||||
this.watchDisplayResize();
|
||||
},
|
||||
unmounted: function () {
|
||||
unmounted() {
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
this.composition.off('add', this.addChild);
|
||||
this.composition.off('remove', this.removeChild);
|
||||
@@ -623,6 +623,7 @@ export default {
|
||||
return this.openmct.objects.makeKeyString(item.identifier) !== keyString;
|
||||
}
|
||||
});
|
||||
this.layoutItems = layoutItems;
|
||||
this.mutate('configuration.items', layoutItems);
|
||||
this.clearSelection();
|
||||
},
|
||||
|
||||
@@ -169,7 +169,7 @@ export default {
|
||||
if (selected) {
|
||||
this.selectedFaults[fault.id] = fault;
|
||||
} else {
|
||||
this.$delete(this.selectedFaults, fault.id);
|
||||
delete this.selectedFaults[fault.id];
|
||||
}
|
||||
|
||||
const selectedFaults = Object.values(this.selectedFaults);
|
||||
|
||||
@@ -173,14 +173,14 @@ export default {
|
||||
|
||||
if (globalFiltersToRemove.length > 0) {
|
||||
globalFiltersToRemove.forEach((key) => {
|
||||
this.$delete(this.globalFilters, key);
|
||||
this.$delete(this.globalMetadata, key);
|
||||
delete this.globalFilters[key];
|
||||
delete this.globalMetadata[key];
|
||||
});
|
||||
this.mutateConfigurationGlobalFilters();
|
||||
}
|
||||
|
||||
this.$delete(this.children, keyString);
|
||||
this.$delete(this.persistedFilters, keyString);
|
||||
delete this.children[keyString];
|
||||
delete this.persistedFilters[keyString];
|
||||
this.mutateConfigurationFilters();
|
||||
},
|
||||
getGlobalFiltersToRemove(keyString) {
|
||||
|
||||
@@ -476,7 +476,6 @@ export default {
|
||||
{
|
||||
label: 'Lock Page',
|
||||
callback: () => {
|
||||
let sections = this.getSections();
|
||||
this.selectedPage.isLocked = true;
|
||||
|
||||
// cant be default if it's locked
|
||||
@@ -488,7 +487,7 @@ export default {
|
||||
this.selectedSection.isLocked = true;
|
||||
}
|
||||
|
||||
mutateObject(this.openmct, this.domainObject, 'configuration.sections', sections);
|
||||
mutateObject(this.openmct, this.domainObject, 'configuration.sections', this.sections);
|
||||
|
||||
if (!this.domainObject.locked) {
|
||||
mutateObject(this.openmct, this.domainObject, 'locked', true);
|
||||
@@ -708,9 +707,6 @@ export default {
|
||||
getSection(id) {
|
||||
return this.sections.find((s) => s.id === id);
|
||||
},
|
||||
getSections() {
|
||||
return this.domainObject.configuration.sections || [];
|
||||
},
|
||||
getSearchResults() {
|
||||
if (!this.search.length) {
|
||||
return [];
|
||||
|
||||
@@ -106,9 +106,8 @@ export default {
|
||||
watch: {
|
||||
isLocked(value) {
|
||||
if (value === true) {
|
||||
let index = this.menuActions.findIndex((item) => item.id === 'removeEmbed');
|
||||
|
||||
this.$delete(this.menuActions, index);
|
||||
const index = this.menuActions.findIndex((item) => item.id === 'removeEmbed');
|
||||
this.menuActions.splice(index, 1);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -140,7 +139,7 @@ export default {
|
||||
onItemClicked: () => this.openSnapshot()
|
||||
};
|
||||
|
||||
this.menuActions = [viewSnapshot];
|
||||
this.menuActions.splice(0, this.menuActions.length, viewSnapshot);
|
||||
}
|
||||
|
||||
const navigateToItem = {
|
||||
@@ -167,7 +166,7 @@ export default {
|
||||
onItemClicked: () => this.previewEmbed()
|
||||
};
|
||||
|
||||
this.menuActions = this.menuActions.concat([quickView, navigateToItem, navigateToItemInTime]);
|
||||
this.menuActions.push(...[quickView, navigateToItem, navigateToItemInTime]);
|
||||
|
||||
if (!this.isLocked) {
|
||||
const removeEmbed = {
|
||||
|
||||
@@ -232,7 +232,7 @@ export default {
|
||||
removeChild(childIdentifier) {
|
||||
const id = this.openmct.objects.makeKeyString(childIdentifier);
|
||||
|
||||
this.$delete(this.tickWidthMap, id);
|
||||
delete this.tickWidthMap[id];
|
||||
|
||||
const childObj = this.compositionObjects.filter((c) => {
|
||||
const identifier = c.keyString;
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
@panAxis="pan"
|
||||
@zoomAxis="zoom"
|
||||
/>
|
||||
<div class="c-not-button c-not-button--compact c-compact-tc__gear icon-gear"></div>
|
||||
<div role="button" class="c-not-button c-not-button--compact c-compact-tc__gear icon-gear" aria-label="Time Conductor Settings"></div>
|
||||
|
||||
<conductor-pop-up
|
||||
v-if="showConductorPopup"
|
||||
|
||||
@@ -1,29 +1,38 @@
|
||||
/***************************************************************************** * Open MCT Web,
|
||||
Copyright (c) 2014-2023, United States Government * as represented by the Administrator of the
|
||||
National Aeronautics and Space * Administration. All rights reserved. * * Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
<template>
|
||||
<div v-if="readOnly === false" ref="clockButton" class="c-tc-input-popup__options">
|
||||
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">
|
||||
<button
|
||||
class="c-button--menu js-clock-button"
|
||||
:class="[buttonCssClass, selectedClock.cssClass]"
|
||||
aria-label="Time Conductor Clock Menu"
|
||||
@click.prevent.stop="showClocksMenu"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedClock.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="c-compact-tc__setting-value__elem" :title="`Clock: ${selectedClock.name}`">
|
||||
<div v-else class="c-compact-tc__setting-value__elem" aria-label="Time Conductor Clock">
|
||||
{{ selectedClock.name }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
<div
|
||||
class="c-compact-tc__setting-value u-fade-truncate--lg --no-sep"
|
||||
:title="`Start bounds: ${formattedBounds.start}`"
|
||||
aria-label="Start bounds"
|
||||
>
|
||||
{{ formattedBounds.start }}
|
||||
</div>
|
||||
@@ -39,6 +40,7 @@
|
||||
<div
|
||||
class="c-compact-tc__setting-value u-fade-truncate--lg --no-sep"
|
||||
:title="`End bounds: ${formattedBounds.end}`"
|
||||
aria-label="End bounds"
|
||||
>
|
||||
{{ formattedBounds.end }}
|
||||
</div>
|
||||
|
||||
@@ -26,12 +26,13 @@
|
||||
class="c-button--menu js-mode-button"
|
||||
:class="[buttonCssClass, selectedMode.cssClass]"
|
||||
@click.prevent.stop="showModesMenu"
|
||||
aria-label="Time Conductor Mode Menu"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedMode.name }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="c-compact-tc__setting-value__elem" :title="`Mode: ${selectedMode.name}`">
|
||||
<div role="button" v-else class="c-compact-tc__setting-value__elem" aria-label="Time Conductor Mode">
|
||||
{{ selectedMode.name }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
class="c-button--menu c-time-system-button"
|
||||
:class="[buttonCssClass]"
|
||||
@click.prevent.stop="showTimeSystemMenu"
|
||||
aria-label="Time Conductor Time System"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedTimeSystem.name }}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
/***************************************************************************** * Open MCT Web,
|
||||
Copyright (c) 2014-2023, United States Government * as represented by the Administrator of the
|
||||
National Aeronautics and Space * Administration. All rights reserved. * * Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2023, 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.
|
||||
-->
|
||||
<template>
|
||||
<div ref="clockMenuButton" class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
||||
<div class="c-menu-button c-ctrl-wrapper c-ctrl-wrapper--menus-left">
|
||||
@@ -18,6 +26,7 @@ available * at runtime from the About dialog for additional information.
|
||||
v-if="selectedClock"
|
||||
class="c-icon-button c-button--menu js-clock-button"
|
||||
:class="[buttonCssClass, selectedClock.cssClass]"
|
||||
aria-label="Independent Time Conductor Clock Menu"
|
||||
@click.prevent.stop="showClocksMenu"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedClock.name }}</span>
|
||||
@@ -48,7 +57,7 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
data() {
|
||||
const activeClock = this.getActiveClock();
|
||||
|
||||
return {
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
<button
|
||||
class="c-icon-button c-button--menu js-mode-button"
|
||||
:class="[buttonCssClass, selectedMode.cssClass]"
|
||||
aria-label="Independent Time Conductor Mode Menu"
|
||||
@click.prevent.stop="showModesMenu"
|
||||
>
|
||||
<span class="c-button__label">{{ selectedMode.name }}</span>
|
||||
|
||||
@@ -28,17 +28,17 @@
|
||||
{ 'is-expanded': independentTCEnabled }
|
||||
]"
|
||||
>
|
||||
<toggle-switch
|
||||
<ToggleSwitch
|
||||
id="independentTCToggle"
|
||||
class="c-toggle-switch--mini"
|
||||
:checked="independentTCEnabled"
|
||||
:title="toggleTitle"
|
||||
:name="toggleTitle"
|
||||
@change="toggleIndependentTC"
|
||||
/>
|
||||
|
||||
<ConductorModeIcon />
|
||||
|
||||
<conductor-inputs-fixed
|
||||
<ConductorInputsFixed
|
||||
v-if="showFixedInputs"
|
||||
class="c-compact-tc__bounds--fixed"
|
||||
:object-path="objectPath"
|
||||
@@ -46,7 +46,7 @@
|
||||
:compact="true"
|
||||
/>
|
||||
|
||||
<conductor-inputs-realtime
|
||||
<ConductorInputsRealtime
|
||||
v-if="showRealtimeInputs"
|
||||
class="c-compact-tc__bounds--real-time"
|
||||
:object-path="objectPath"
|
||||
@@ -55,10 +55,12 @@
|
||||
/>
|
||||
<div
|
||||
v-if="independentTCEnabled"
|
||||
role="button"
|
||||
class="c-not-button c-not-button--compact c-compact-tc__gear icon-gear"
|
||||
aria-label="Independent Time Conductor Settings"
|
||||
></div>
|
||||
|
||||
<conductor-pop-up
|
||||
<ConductorPopUp
|
||||
v-if="showConductorPopup"
|
||||
ref="conductorPopup"
|
||||
:object-path="objectPath"
|
||||
@@ -145,7 +147,7 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
toggleTitle() {
|
||||
return `${this.independentTCEnabled ? 'Disable' : 'Enable'} independent Time Conductor`;
|
||||
return `${this.independentTCEnabled ? 'Disable' : 'Enable'} Independent Time Conductor`;
|
||||
},
|
||||
showFixedInputs() {
|
||||
return this.isFixed && this.independentTCEnabled;
|
||||
|
||||
@@ -42,8 +42,11 @@ export default {
|
||||
methods: {
|
||||
initializePopup() {
|
||||
this.conductorPopup = this.$refs.conductorPopup.$el;
|
||||
document.body.appendChild(this.conductorPopup); // remove from container as it (and it's ancestors) have overflow:hidden
|
||||
|
||||
// we need to append it the first time since the popup has overflow:hidden
|
||||
// then we show/hide based on the flag
|
||||
if (this.conductorPopup.parentNode !== document.body) {
|
||||
document.body.appendChild(this.conductorPopup);
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
window.addEventListener('resize', this.positionBox);
|
||||
document.addEventListener('click', this.handleClickAway);
|
||||
@@ -97,11 +100,6 @@ export default {
|
||||
if (!this.conductorPopup) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.conductorPopup.parentNode === document.body) {
|
||||
document.body.removeChild(this.conductorPopup);
|
||||
}
|
||||
|
||||
this.showConductorPopup = false;
|
||||
this.conductorPopup = null;
|
||||
this.positionX = -10000; // reset it off screan
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
aria-label="Start date"
|
||||
@change="validateAllBounds('startDate')"
|
||||
/>
|
||||
<date-picker
|
||||
@@ -34,6 +35,7 @@
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
aria-label="Start time"
|
||||
@change="validateAllBounds('startDate')"
|
||||
/>
|
||||
</div>
|
||||
@@ -48,6 +50,7 @@
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
aria-label="End date"
|
||||
@change="validateAllBounds('endDate')"
|
||||
/>
|
||||
<date-picker
|
||||
@@ -67,6 +70,7 @@
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
aria-label="End time"
|
||||
@change="validateAllBounds('endDate')"
|
||||
/>
|
||||
</div>
|
||||
@@ -75,9 +79,10 @@
|
||||
<button
|
||||
class="c-button c-button--major icon-check"
|
||||
:disabled="isDisabled"
|
||||
aria-label="Submit time bounds"
|
||||
@click.prevent="submit"
|
||||
></button>
|
||||
<button class="c-button icon-x" @click.prevent="hide"></button>
|
||||
<button class="c-button icon-x" @click.prevent="hide" aria-label="Discard time bounds"></button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
min="0"
|
||||
max="23"
|
||||
title="Enter 0 - 23"
|
||||
aria-label="Start offset hours"
|
||||
@change="validate()"
|
||||
@keyup="validate()"
|
||||
@focusin="selectAll($event)"
|
||||
@@ -37,6 +38,7 @@
|
||||
max="59"
|
||||
title="Enter 0 - 59"
|
||||
step="1"
|
||||
aria-label="Start offset minutes"
|
||||
@change="validate()"
|
||||
@keyup="validate()"
|
||||
@focusin="selectAll($event)"
|
||||
@@ -55,6 +57,7 @@
|
||||
max="59"
|
||||
title="Enter 0 - 59"
|
||||
step="1"
|
||||
aria-label="Start offset seconds"
|
||||
@change="validate()"
|
||||
@keyup="validate()"
|
||||
@focusin="selectAll($event)"
|
||||
@@ -75,6 +78,7 @@
|
||||
min="0"
|
||||
max="23"
|
||||
title="Enter 0 - 23"
|
||||
aria-label="End offset hours"
|
||||
@change="validate()"
|
||||
@keyup="validate()"
|
||||
@focusin="selectAll($event)"
|
||||
@@ -111,6 +115,7 @@
|
||||
max="59"
|
||||
title="Enter 0 - 59"
|
||||
step="1"
|
||||
aria-label="End offset seconds"
|
||||
@change="validate()"
|
||||
@keyup="validate()"
|
||||
@focusin="selectAll($event)"
|
||||
@@ -123,9 +128,14 @@
|
||||
<button
|
||||
class="c-button c-button--major icon-check"
|
||||
:disabled="isDisabled"
|
||||
aria-label="Submit time offsets"
|
||||
@click.prevent="submit"
|
||||
></button>
|
||||
<button class="c-button icon-x" @click.prevent="hide"></button>
|
||||
<button
|
||||
class="c-button icon-x"
|
||||
aria-label="Discard time offsets"
|
||||
@click.prevent="hide"
|
||||
></button>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
@@ -167,7 +177,7 @@ export default {
|
||||
methods: {
|
||||
format(ref) {
|
||||
const curVal = this[ref];
|
||||
this[ref] = curVal.padStart(2, '0');
|
||||
this[ref] = curVal.toString().padStart(2, '0');
|
||||
},
|
||||
validate() {
|
||||
let disabled = false;
|
||||
|
||||
@@ -103,9 +103,8 @@ export default {
|
||||
},
|
||||
inject: ['openmct', 'domainObject', 'path', 'composition'],
|
||||
data() {
|
||||
this.planObjects = [];
|
||||
|
||||
return {
|
||||
planObjects: [],
|
||||
viewBounds: undefined,
|
||||
height: 0,
|
||||
planActivities: [],
|
||||
@@ -345,12 +344,13 @@ export default {
|
||||
let activities = [];
|
||||
|
||||
groups.forEach((key) => {
|
||||
activities = activities.concat(this.planData[key]);
|
||||
// Create new objects so Vue 3 can detect any changes
|
||||
activities = activities.concat(JSON.parse(JSON.stringify(this.planData[key])));
|
||||
});
|
||||
// filter activities first, then sort by start time
|
||||
activities = activities.filter(this.filterActivities).sort(this.sortByStartTime);
|
||||
activities = this.applyStyles(activities);
|
||||
this.planActivities = activities;
|
||||
this.planActivities = [...activities];
|
||||
//We need to wait for the next tick since we need the height of the row from the DOM
|
||||
this.$nextTick(this.setScrollTop);
|
||||
},
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
<template>
|
||||
<div class="c-inspector js-inspector">
|
||||
<object-name />
|
||||
<InspectorTabs :selection="selection" :is-editing="isEditing" @select-tab="selectTab" />
|
||||
<InspectorViews :selection="selection" :selected-tab="selectedTab" />
|
||||
<InspectorTabs :is-editing="isEditing" @select-tab="selectTab" />
|
||||
<InspectorViews :selected-tab="selectedTab" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -48,20 +48,10 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
selection: this.openmct.selection.get(),
|
||||
selectedTab: undefined
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.selection.on('change', this.setSelection);
|
||||
},
|
||||
unmounted() {
|
||||
this.openmct.selection.off('change', this.setSelection);
|
||||
},
|
||||
methods: {
|
||||
setSelection(selection) {
|
||||
this.selection = selection;
|
||||
},
|
||||
selectTab(tab) {
|
||||
this.selectedTab = tab;
|
||||
}
|
||||
|
||||
@@ -40,21 +40,11 @@
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
selection: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
isEditing: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
selection: {
|
||||
type: Array,
|
||||
default: []
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tabs: [],
|
||||
@@ -69,12 +59,6 @@ export default {
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selection: {
|
||||
handler() {
|
||||
this.updateSelection();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
visibleTabs: {
|
||||
handler() {
|
||||
this.selectDefaultTabIfSelectedNotVisible();
|
||||
@@ -82,9 +66,16 @@ export default {
|
||||
deep: true
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateSelection();
|
||||
this.openmct.selection.on('change', this.updateSelection);
|
||||
},
|
||||
unmounted() {
|
||||
this.openmct.selection.off('change', this.updateSelection);
|
||||
},
|
||||
methods: {
|
||||
updateSelection() {
|
||||
const inspectorViews = this.openmct.inspectorViews.get(this.selection);
|
||||
const inspectorViews = this.openmct.inspectorViews.get(this.openmct.selection.get());
|
||||
|
||||
this.tabs = inspectorViews.map((view) => {
|
||||
return {
|
||||
|
||||
@@ -31,29 +31,24 @@ export default {
|
||||
selectedTab: {
|
||||
type: Object,
|
||||
default: undefined
|
||||
},
|
||||
selection: {
|
||||
type: Array,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
selection: {
|
||||
handler() {
|
||||
this.updateSelectionViews();
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
selectedTab() {
|
||||
this.clearAndShowViewsForTab();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.updateSelectionViews();
|
||||
this.openmct.selection.on('change', this.updateSelectionViews);
|
||||
},
|
||||
unmounted() {
|
||||
this.openmct.selection.off('change', this.updateSelectionViews);
|
||||
},
|
||||
methods: {
|
||||
updateSelectionViews(selection) {
|
||||
this.clearViews();
|
||||
this.selectedViews = this.openmct.inspectorViews.get(this.selection);
|
||||
this.selectedViews = this.openmct.inspectorViews.get(this.openmct.selection.get());
|
||||
this.showViewsForTab();
|
||||
},
|
||||
clearViews() {
|
||||
|
||||
@@ -351,8 +351,10 @@ export default {
|
||||
|
||||
this.endItemLoad(parentPath);
|
||||
|
||||
this.treeItems.splice(parentIndex + 1, 0, ...childrenItems);
|
||||
|
||||
const newTreeItems = [...this.treeItems];
|
||||
newTreeItems.splice(parentIndex + 1, 0, ...childrenItems);
|
||||
this.treeItems = [...newTreeItems];
|
||||
|
||||
if (!this.isTreeItemOpen(parentItem)) {
|
||||
this.openTreeItems.push(parentPath);
|
||||
}
|
||||
@@ -388,7 +390,9 @@ export default {
|
||||
|
||||
return true;
|
||||
});
|
||||
this.openTreeItems.splice(pathIndex, 1);
|
||||
const newOpenTreeItems = [...this.openTreeItems];
|
||||
newOpenTreeItems.splice(pathIndex, 1);
|
||||
this.openTreeItems = [...newOpenTreeItems];
|
||||
this.removeCompositionListenerFor(path);
|
||||
},
|
||||
closeTreeItem(item) {
|
||||
@@ -703,11 +707,13 @@ export default {
|
||||
});
|
||||
|
||||
// Splice in all of the sorted descendants
|
||||
this.treeItems.splice(
|
||||
this.treeItems.indexOf(parentItem) + 1,
|
||||
const newTreeItems = [...this.treeItems];
|
||||
newTreeItems.splice(
|
||||
newTreeItems.indexOf(parentItem) + 1,
|
||||
sortedTreeItems.length,
|
||||
...sortedTreeItems
|
||||
);
|
||||
this.treeItems = [...newTreeItems];
|
||||
},
|
||||
buildNavigationPath(objectPath) {
|
||||
return (
|
||||
@@ -792,7 +798,9 @@ export default {
|
||||
}
|
||||
|
||||
const removeIndex = this.getTreeItemIndex(item.navigationPath);
|
||||
this.treeItems.splice(removeIndex, 1);
|
||||
const newTreeItems = [...this.treeItems];
|
||||
newTreeItems.splice(removeIndex, 1);
|
||||
this.treeItems = [...newTreeItems];
|
||||
},
|
||||
addItemToTreeBefore(addItem, beforeItem) {
|
||||
const addIndex = this.getTreeItemIndex(beforeItem.navigationPath);
|
||||
@@ -805,7 +813,9 @@ export default {
|
||||
this.addItemToTree(addItem, addIndex + 1);
|
||||
},
|
||||
addItemToTree(addItem, index) {
|
||||
this.treeItems.splice(index, 0, addItem);
|
||||
const newTreeItems = [...this.treeItems];
|
||||
newTreeItems.splice(index, 0, addItem);
|
||||
this.treeItems = [...newTreeItems];
|
||||
|
||||
if (this.isTreeItemOpen(addItem)) {
|
||||
this.openTreeItem(addItem);
|
||||
|
||||
@@ -50,7 +50,7 @@ export default {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
let actionsCollection = this.openmct.actions.getActionsCollection(this.objectPath);
|
||||
let actionsCollection = this.openmct.actions.getActionsCollection(toRaw(this.objectPath));
|
||||
let actions = actionsCollection.getVisibleActions();
|
||||
let sortedActions = this.openmct.actions._groupAndSortActions(actions);
|
||||
|
||||
|
||||