Compare commits

..

20 Commits

Author SHA1 Message Date
Shefali
9f7a88090c Remove debouncing 2023-03-24 15:00:54 -07:00
Shefali
9fcebf8b11 Reduce debounce time 2023-03-24 14:52:35 -07:00
Shefali
d68d7bdd8e Fix formatting for local clock 2023-03-24 14:23:29 -07:00
Shefali
88cbd8e40c Check for clock being undefined 2023-03-24 10:33:49 -07:00
Shefali
d4bce52fb0 Remove unused code 2023-03-24 07:04:51 -07:00
Shefali
93214c235a Use formatting from clock when available. When clock changes, update the timestamp. 2023-03-24 06:50:41 -07:00
Shefali
907da30516 Pass openmct to format function 2023-03-24 05:57:30 -07:00
Shefali
eb9e0d8d4d Format Time from the clock 2023-03-23 15:59:59 -07:00
Shefali
eb3129bdb0 Use parseTime to get formatted time. 2023-03-23 15:54:04 -07:00
Shefali
d9877759d3 Change moment to use utc parsing 2023-03-23 15:02:53 -07:00
Shefali
ac21c1b70c Debounce the update timestamp call 2023-03-22 13:36:42 -07:00
Shefali
0ea776f688 Remote ticker for timelist and rename a function for readability 2023-03-22 13:11:18 -07:00
dependabot[bot]
3e3dc7dd83 chore(deps-dev): bump webpack from 5.74.0 to 5.76.2 (#6440)
Bumps [webpack](https://github.com/webpack/webpack) from 5.74.0 to 5.76.2.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.74.0...v5.76.2)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-22 19:22:53 +00:00
Charles Hacskaylo
50742c4f82 Hide Flexible Layout header buttons when frame is hidden (#6486)
- Hide nested frame header buttons for Flexible Layouts as well as Display Layouts.
- Adjust z-index of frame control header buttons.
2023-03-21 17:24:41 -07:00
Vitor Henckel
2f04add2a3 fix(#6408): Zooming in the corner of an image makes it fly away (#6410)
* fix(#6480): Zooming in the corner of an image makes it fly away

* fix: keeping layers in the right place even when zoomed in
2023-03-22 00:15:02 +00:00
Charles Hacskaylo
0ce5060246 Fix Imagery local controls z-index (#6482)
- Corrected z-index for imagery local controls.
2023-03-22 00:02:34 +00:00
Scott Bell
00353cdccf Cancel annotation selections if you click outside the plot component (#6476)
* resolve conflicts

* resolve conflicts

* more selectively add listeners

* add and fix tests

* address PR review comments

* test(e2e): stabilize flaky overlayPlot test

---------

Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
Co-authored-by: Jesse Mazzella <jesse.d.mazzella@nasa.gov>
2023-03-21 16:53:24 -07:00
dependabot[bot]
a1ac209d74 chore(deps-dev): bump plotly.js-gl2d-dist from 2.17.1 to 2.20.0 (#6441)
Bumps [plotly.js-gl2d-dist](https://github.com/plotly/plotly.js) from 2.17.1 to 2.20.0.
- [Release notes](https://github.com/plotly/plotly.js/releases)
- [Changelog](https://github.com/plotly/plotly.js/blob/master/CHANGELOG.md)
- [Commits](https://github.com/plotly/plotly.js/compare/v2.17.1...v2.20.0)

---
updated-dependencies:
- dependency-name: plotly.js-gl2d-dist
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-21 13:57:59 -07:00
dependabot[bot]
bdd8477b54 chore(deps-dev): bump sass from 1.57.1 to 1.59.3 (#6442)
Bumps [sass](https://github.com/sass/dart-sass) from 1.57.1 to 1.59.3.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.57.1...1.59.3)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-21 19:27:17 +00:00
dependabot[bot]
f690f36bfb chore(deps-dev): bump sass-loader from 13.2.0 to 13.2.1 (#6480)
Bumps [sass-loader](https://github.com/webpack-contrib/sass-loader) from 13.2.0 to 13.2.1.
- [Release notes](https://github.com/webpack-contrib/sass-loader/releases)
- [Changelog](https://github.com/webpack-contrib/sass-loader/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack-contrib/sass-loader/compare/v13.2.0...v13.2.1)

---
updated-dependencies:
- dependency-name: sass-loader
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: John Hill <john.c.hill@nasa.gov>
2023-03-21 12:11:42 -07:00
12 changed files with 111 additions and 51 deletions

View File

@@ -268,6 +268,9 @@ async function getCanvasPixelsWithData(page) {
* @param {import('@playwright/test').Page} page
*/
async function assertLimitLinesExistAndAreVisible(page) {
// Wait for plot series data to load
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
// Wait for limit lines to be created
await page.waitForSelector('.js-limit-area', { state: 'attached' });
const limitLineCount = await page.locator('.c-plot-limit-line').count();
// There should be 10 limit lines created by default

View File

@@ -28,6 +28,14 @@ const { test, expect } = require('../../../../pluginFixtures');
const { createDomainObjectWithDefaults, setRealTimeMode, setFixedTimeMode } = require('../../../../appActions');
test.describe('Plot Tagging', () => {
/**
* Given a canvas and a set of points, tags the points on the canvas.
* @param {import('@playwright/test').Page} page
* @param {HTMLCanvasElement} canvas a telemetry item with a plot
* @param {Number} xEnd a telemetry item with a plot
* @param {Number} yEnd a telemetry item with a plot
* @returns {Promise}
*/
async function createTags({page, canvas, xEnd, yEnd}) {
await canvas.hover({trial: true});
@@ -64,12 +72,20 @@ test.describe('Plot Tagging', () => {
await page.getByText('Science').click();
}
async function testTelemetryItem(page, canvas, telemetryItem) {
/**
* Given a telemetry item (e.g., a Sine Wave Generator) with a plot, tests that the plot can be tagged.
* @param {import('@playwright/test').Page} page
* @param {import('../../../../appActions').CreatedObjectInfo} telemetryItem a telemetry item with a plot
* @returns {Promise}
*/
async function testTelemetryItem(page, telemetryItem) {
// Check that telemetry item also received the tag
await page.goto(telemetryItem.url);
await expect(page.getByText('No tags to display for this item')).toBeVisible();
const canvas = page.locator('canvas').nth(1);
//Wait for canvas to stablize.
await canvas.hover({trial: true});
@@ -85,19 +101,31 @@ test.describe('Plot Tagging', () => {
await expect(page.getByText('Driving')).toBeHidden();
}
async function basicTagsTests(page, canvas) {
// Search for Science
/**
* Given a page, tests that tags are searchable, deletable, and persist across reloads.
* @param {import('@playwright/test').Page} page
* @returns {Promise}
*/
async function basicTagsTests(page) {
// Search for Driving
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
await expect(page.locator('[aria-label="Search Result"]').nth(0)).toContainText("Science");
await expect(page.locator('[aria-label="Search Result"]').nth(0)).not.toContainText("Drilling");
// Clicking elsewhere should cause annotation selection to be cleared
await expect(page.getByText('No tags to display for this item')).toBeVisible();
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('driv');
// click on the search result
await page.getByRole('searchbox', { name: 'OpenMCT Search' }).getByText(/Sine Wave/).first().click();
// Delete Driving
await page.hover('[aria-label="Tag"]:has-text("Driving")');
await page.locator('[aria-label="Remove tag Driving"]').click();
await expect(page.locator('[aria-label="Tags Inspector"]')).toContainText("Science");
await expect(page.locator('[aria-label="Tags Inspector"]')).not.toContainText("Driving");
// Search for Science
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
await expect(page.locator('[aria-label="Search Result"]').nth(0)).toContainText("Science");
await expect(page.locator('[aria-label="Search Result"]').nth(0)).not.toContainText("Drilling");
// Search for Driving
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').click();
@@ -109,12 +137,13 @@ test.describe('Plot Tagging', () => {
page.reload(),
page.waitForLoadState('networkidle')
]);
// wait for plot progress bar to disappear
await page.locator('.l-view-section.c-progress-bar').waitFor({ state: 'detached' });
// wait for plots to load
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
await page.getByText('Annotations').click();
await expect(page.getByText('No tags to display for this item')).toBeVisible();
const canvas = page.locator('canvas').nth(1);
// click on the tagged plot point
await canvas.click({
position: {
@@ -171,8 +200,8 @@ test.describe('Plot Tagging', () => {
// changing to fixed time mode rebuilds canvas?
canvas = page.locator('canvas').nth(1);
await basicTagsTests(page, canvas);
await testTelemetryItem(page, canvas, alphaSineWave);
await basicTagsTests(page);
await testTelemetryItem(page, alphaSineWave);
// set to real time mode
await setRealTimeMode(page);
@@ -182,8 +211,8 @@ test.describe('Plot Tagging', () => {
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('sc');
// click on the search result
await page.getByRole('searchbox', { name: 'OpenMCT Search' }).getByText('Alpha Sine Wave').first().click();
// wait for plot progress bar to disappear
await page.locator('.l-view-section.c-progress-bar').waitFor({ state: 'detached' });
// wait for plots to load
await expect(page.locator('.js-series-data-loaded')).toBeVisible();
// expect plot to be paused
await expect(page.locator('[title="Resume displaying real-time data"]')).toBeVisible();
@@ -202,7 +231,7 @@ test.describe('Plot Tagging', () => {
xEnd: 700,
yEnd: 480
});
await basicTagsTests(page, canvas);
await basicTagsTests(page);
});
test('Tags work with Stacked Plots', async ({ page }) => {
@@ -232,7 +261,7 @@ test.describe('Plot Tagging', () => {
xEnd: 700,
yEnd: 215
});
await basicTagsTests(page, canvas);
await testTelemetryItem(page, canvas, alphaSineWave);
await basicTagsTests(page);
await testTelemetryItem(page, alphaSineWave);
});
});

View File

@@ -52,12 +52,12 @@
"painterro": "1.2.78",
"playwright-core": "1.29.0",
"plotly.js-basic-dist": "2.17.0",
"plotly.js-gl2d-dist": "2.17.1",
"plotly.js-gl2d-dist": "2.20.0",
"printj": "1.3.1",
"resolve-url-loader": "5.0.0",
"sanitize-html": "2.10.0",
"sass": "1.57.1",
"sass-loader": "13.2.0",
"sass": "1.59.3",
"sass-loader": "13.2.1",
"sinon": "15.0.1",
"style-loader": "^3.3.1",
"typescript": "4.9.5",
@@ -66,7 +66,7 @@
"vue-eslint-parser": "9.1.0",
"vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14",
"webpack": "5.74.0",
"webpack": "5.76.2",
"webpack-cli": "5.0.0",
"webpack-dev-server": "4.11.1",
"webpack-merge": "5.8.0"

View File

@@ -43,7 +43,7 @@
</div>
<div
v-if="!hideOptions && filteredOptions.length > 0"
class="c-menu c-input--autocomplete__options"
class="c-menu c-input--autocomplete__options js-autocomplete-options"
aria-label="Autocomplete Options"
@blur="hideOptions = true"
>

View File

@@ -322,7 +322,7 @@ export default {
rgba(125,125,125,.2) 8px
)`
) : ''}`,
transform: `scale(${this.zoomFactor}) translate(${this.imageTranslateX}px, ${this.imageTranslateY}px)`,
transform: `scale(${this.zoomFactor}) translate(${this.imageTranslateX / 2}px, ${this.imageTranslateY / 2}px)`,
transition: `${!this.pan && this.animateZoom ? 'transform 250ms ease-in' : 'initial'}`,
width: `${this.sizedImageWidth}px`,
height: `${this.sizedImageHeight}px`
@@ -709,7 +709,7 @@ export default {
getVisibleLayerStyles(layer) {
return {
backgroundImage: `url(${layer.source})`,
transform: `scale(${this.zoomFactor}) translate(${this.imageTranslateX}px, ${this.imageTranslateY}px)`,
transform: `scale(${this.zoomFactor}) translate(${this.imageTranslateX / 2}px, ${this.imageTranslateY / 2}px)`,
transition: `${!this.pan && this.animateZoom ? 'transform 250ms ease-in' : 'initial'}`
};
},

View File

@@ -195,7 +195,7 @@
margin-bottom: 1px;
padding-bottom: $interiorMarginSm;
&.animate-scroll {
scroll-behavior: smooth;
scroll-behavior: smooth;
}
}
@@ -320,7 +320,7 @@
flex-direction: row;
position: absolute;
left: $interiorMargin; top: $interiorMargin;
z-index: 70;
z-index: 10;
background: $colorLocalControlOvrBg;
border-radius: $basicCr;
align-items: center;

View File

@@ -22,7 +22,9 @@
<template>
<div
v-if="loaded"
ref="plot"
class="gl-plot"
:class="{ 'js-series-data-loaded' : seriesDataLoaded }"
>
<slot></slot>
<div class="plot-wrapper-axis-and-display-area flex-elem grows">
@@ -347,6 +349,9 @@ export default {
const parentLeftTickWidth = this.parentYTickWidth.leftTickWidth;
return parentLeftTickWidth || leftTickWidth;
},
seriesDataLoaded() {
return ((this.pending === 0) && this.loaded);
}
},
watch: {
@@ -412,6 +417,7 @@ export default {
this.openmct.selection.off('change', this.updateSelection);
document.removeEventListener('keydown', this.handleKeyDown);
document.removeEventListener('keyup', this.handleKeyUp);
document.body.removeEventListener('click', this.cancelSelection);
this.destroy();
},
methods: {
@@ -444,6 +450,19 @@ export default {
//This section is common to all entry points for annotation display
this.prepareExistingAnnotationSelection(selectedAnnotations);
},
cancelSelection(event) {
if (this.$refs?.plot) {
const clickedInsidePlot = this.$refs.plot.contains(event.target);
const clickedInsideInspector = event.target.closest('.js-inspector') !== null;
const clickedOption = event.target.closest('.js-autocomplete-options') !== null;
if (!clickedInsidePlot && !clickedInsideInspector && !clickedOption) {
this.rectangles = [];
this.annotationSelections = [];
this.selectPlot();
document.body.removeEventListener('click', this.cancelSelection);
}
}
},
waitForAxesToLoad() {
return new Promise(resolve => {
// When there is no plot data, the ranges can be undefined
@@ -1276,6 +1295,8 @@ export default {
}
this.openmct.selection.select(selection, true);
document.body.addEventListener('click', this.cancelSelection);
},
selectNewPlotAnnotations(boundingBoxPerYAxis, pointsInBox, event) {
let targetDomainObjects = {};

View File

@@ -46,6 +46,7 @@ export default class RemoteClock extends DefaultClock {
this.timeTelemetryObject = undefined;
this.parseTime = undefined;
this.formatTime = undefined;
this.metadata = undefined;
this.lastTick = 0;
@@ -137,6 +138,10 @@ export default class RemoteClock extends DefaultClock {
this.parseTime = (datum) => {
return timeFormatter.parse(datum);
};
this.formatTime = (datum) => {
return timeFormatter.format(datum);
};
}
/**

View File

@@ -38,9 +38,8 @@
import {getValidatedData} from "../plan/util";
import ListView from '../../ui/components/List/ListView.vue';
import {getPreciseDuration} from "../../utils/duration";
import ticker from 'utils/clock/Ticker';
import {SORT_ORDER_OPTIONS} from "./constants";
import _ from 'lodash';
import moment from "moment";
import { v4 as uuid } from 'uuid';
@@ -53,16 +52,26 @@ const headerItems = [
isSortable: true,
property: 'start',
name: 'Start Time',
format: function (value, object) {
return `${moment(value).format(TIME_FORMAT)}Z`;
format: function (value, object, key, openmct) {
const clock = openmct.time.clock();
if (clock && clock.formatTime) {
return clock.formatTime(value);
} else {
return `${moment(value).format(TIME_FORMAT)}Z`;
}
}
}, {
defaultDirection: true,
isSortable: true,
property: 'end',
name: 'End Time',
format: function (value, object) {
return `${moment(value).format(TIME_FORMAT)}Z`;
format: function (value, object, key, openmct) {
const clock = openmct.time.clock();
if (clock && clock.formatTime) {
return clock.formatTime(value);
} else {
return `${moment(value).format(TIME_FORMAT)}Z`;
}
}
}, {
defaultDirection: false,
@@ -119,7 +128,7 @@ export default {
this.unlistenConfig = this.openmct.objects.observe(this.domainObject, 'configuration', this.setViewFromConfig);
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
this.status = this.openmct.status.get(this.domainObject.identifier);
this.unlistenTicker = ticker.listen(this.clearPreviousActivities);
this.openmct.time.on('bounds', this.updateTimestamp);
this.openmct.editor.on('isEditing', this.setEditState);
@@ -144,10 +153,6 @@ export default {
this.unlistenConfig();
}
if (this.unlistenTicker) {
this.unlistenTicker();
}
if (this.removeStatusListener) {
this.removeStatusListener();
}
@@ -192,8 +197,8 @@ export default {
}
},
updateTimestamp(_bounds, isTick) {
if (isTick === true) {
this.timestamp = this.openmct.time.clock().currentValue();
if (isTick === true && this.openmct.time.clock() !== undefined) {
this.updateTimeStampAndListActivities(this.openmct.time.clock().currentValue());
}
},
setViewFromClock(newClock) {
@@ -202,12 +207,11 @@ export default {
if (isFixedTime) {
this.hideAll = false;
this.showAll = true;
// clear invokes listActivities
this.clearPreviousActivities(this.openmct.time.bounds()?.start);
this.updateTimeStampAndListActivities(this.openmct.time.bounds()?.start);
} else {
this.setSort();
this.setViewBounds();
this.listActivities();
this.updateTimeStampAndListActivities(this.openmct.time.clock().currentValue());
}
},
addItem(domainObject) {
@@ -346,12 +350,8 @@ export default {
// sort by start time
this.planActivities = activities.sort(this.sortByStartTime);
},
clearPreviousActivities(time) {
if (time instanceof Date) {
this.timestamp = time.getTime();
} else {
this.timestamp = time;
}
updateTimeStampAndListActivities(time) {
this.timestamp = time;
this.listActivities();
},

View File

@@ -37,7 +37,7 @@ export default {
// eslint-disable-next-line you-dont-need-lodash-underscore/get
let value = _.get(this.item, property.key);
if (property.format) {
value = property.format(value, this.item, property.key);
value = property.format(value, this.item, property.key, this.openmct);
}
values.push({

View File

@@ -61,7 +61,7 @@
pointer-events: none;
position: absolute;
top: 0; right: 0; bottom: auto; left: 0;
z-index: 2;
z-index: 10;
.c-object-label {
visibility: hidden;
@@ -99,6 +99,8 @@
}
}
}
&.c-so-view--flexible-layout,
&.c-so-view--layout {
// For sub-layouts with hidden frames, completely hide the header to avoid overlapping buttons
> .c-so-view__header {

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
<template>
<div class="c-inspector">
<div class="c-inspector js-inspector">
<object-name />
<InspectorTabs
:selection="selection"