Compare commits

...

25 Commits

Author SHA1 Message Date
Alize Nguyen
81799e2146 Merge branch '4777-plots-progress-bar' of https://github.com/nasa/openmct into 4777-plots-progress-bar 2022-06-23 12:12:44 -05:00
Alize Nguyen
373f2e5580 Merge branch 'master' into 4777-plots-progress-bar 2022-06-23 12:05:35 -05:00
Alize Nguyen
d92d4c1768 Put obj directly to model, removed computed prop 2022-06-23 12:02:04 -05:00
Alize Nguyen
9c34de37cc Check if delay is 0 and send, put post in a func 2022-06-23 12:01:08 -05:00
Joshi
c3272f985d Merge branch 'master' of https://github.com/nasa/openmct into 4777-plots-progress-bar 2022-06-14 08:15:23 -07:00
Alize Nguyen
ab71df77df Move loadingUpdate func into plot item for update 2022-06-08 23:54:04 -05:00
Alize Nguyen
586d0393e5 Merge branch '4777-plots-progress-bar' of https://github.com/nasa/openmct into 4777-plots-progress-bar 2022-06-08 22:08:35 -05:00
Alize Nguyen
52902a7c89 Add loading fix for stacked plots 2022-06-08 22:07:26 -05:00
Andrew Henry
4373a34e3b Merge branch 'master' into 4777-plots-progress-bar 2022-06-08 17:27:40 -07:00
John Hill
72a7a334a3 Merge branch 'master' into 4777-plots-progress-bar 2022-06-08 17:10:02 -07:00
Alize Nguyen
47bb4c65e5 Merge branch 'master' into 4777-plots-progress-bar 2022-06-08 15:49:53 -05:00
Alize Nguyen
b3c137bab1 Moved math.max to load delay variable 2022-06-07 12:05:44 -05:00
Alize Nguyen
6785af6916 Add Math.max to timeout to handle negative inputs 2022-06-06 21:46:39 -05:00
John Hill
2e5ee80b02 Merge branch 'master' into 4777-plots-progress-bar 2022-06-06 15:41:59 -07:00
unlikelyzero
ef9512209f Update accessibility 2022-06-06 14:21:59 -07:00
unlikelyzero
383da6fc34 match load order 2022-06-06 12:06:34 -07:00
unlikelyzero
6bfd262484 fix linting errors 2022-06-06 11:16:23 -07:00
unlikelyzero
7088ec5b06 move localstorage file to test-data dir 2022-06-06 11:10:34 -07:00
John Hill
c2b6c63eee Merge branch 'master' into 4777-plots-progress-bar 2022-06-06 10:55:48 -07:00
John Hill
4e0e47a489 Merge branch 'master' into 4777-plots-progress-bar 2022-06-03 08:13:17 -07:00
Alize Nguyen
445df9ecb7 Add loading delay prop to swg 2022-06-02 20:54:05 -05:00
unlikelyzero
113c2fd5ad New pattern for controlled clock 2022-05-25 11:38:41 -07:00
Alize Nguyen
618c7648e1 Merge branch 'master' into 4777-plots-progress-bar 2022-05-24 18:40:26 -05:00
Alize Nguyen
4a0fecd008 Replace load spinner with progress bar for plots 2022-05-24 18:34:48 -05:00
Alize Nguyen
1525638df4 Add .bind(this) to stopLoading() in loadMoreData() 2022-05-24 18:17:52 -05:00
14 changed files with 260 additions and 30 deletions

View File

@@ -0,0 +1,22 @@
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:8080",
"localStorage": [
{
"name": "tcHistory",
"value": "{\"utc\":[{\"start\":1654548551471,\"end\":1654550351471}]}"
},
{
"name": "mct",
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"persisted\":1654550352296,\"modified\":1654550352296},\"527856c0-cced-4b64-bb19-f943432326d0\":{\"identifier\":{\"key\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"namespace\":\"\"},\"name\":\"Unnamed Overlay Plot\",\"type\":\"telemetry.plot.overlay\",\"composition\":[{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"}],\"configuration\":{\"series\":[{\"identifier\":{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"}}],\"yAxis\":{},\"xAxis\":{}},\"modified\":1654550353356,\"location\":\"mine\",\"persisted\":1654550353357},\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\":{\"name\":\"Unnamed Sine Wave Generator\",\"type\":\"generator\",\"identifier\":{\"key\":\"ce88ce37-8bb9-45e1-a85b-bb7e3c8453b9\",\"namespace\":\"\"},\"telemetry\":{\"period\":10,\"amplitude\":1,\"offset\":0,\"dataRateInHz\":1,\"phase\":0,\"randomness\":0,\"loadDelay\":\"5000\"},\"modified\":1654550353350,\"location\":\"527856c0-cced-4b64-bb19-f943432326d0\",\"persisted\":1654550353350}}"
},
{
"name": "mct-tree-expanded",
"value": "[\"/browse/mine\"]"
}
]
}
]
}

View File

@@ -0,0 +1,22 @@
{
"cookies": [],
"origins": [
{
"origin": "http://localhost:8080",
"localStorage": [
{
"name": "tcHistory",
"value": "{\"utc\":[{\"start\":1654537164464,\"end\":1654538964464},{\"start\":1652301954635,\"end\":1652303754635}]}"
},
{
"name": "mct",
"value": "{\"mine\":{\"identifier\":{\"key\":\"mine\",\"namespace\":\"\"},\"name\":\"My Items\",\"type\":\"folder\",\"composition\":[{\"key\":\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\",\"namespace\":\"\"},{\"key\":\"2d02a680-eb7e-4645-bba2-dd298f76efb8\",\"namespace\":\"\"}],\"location\":\"ROOT\",\"persisted\":1654538965703,\"modified\":1654538965703},\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\":{\"name\":\"Unnamed Condition Set\",\"type\":\"conditionSet\",\"identifier\":{\"key\":\"f64bea3b-58a7-4586-8c05-8b651e5f0bfd\",\"namespace\":\"\"},\"configuration\":{\"conditionTestData\":[],\"conditionCollection\":[{\"isDefault\":true,\"id\":\"73f2d9ae-d1f3-4561-b7fc-ecd5df557249\",\"configuration\":{\"name\":\"Default\",\"output\":\"Default\",\"trigger\":\"all\",\"criteria\":[]},\"summary\":\"Default condition\"}]},\"composition\":[],\"telemetry\":{},\"modified\":1652303755999,\"location\":\"mine\",\"persisted\":1652303756002},\"2d02a680-eb7e-4645-bba2-dd298f76efb8\":{\"name\":\"Unnamed Condition Set\",\"type\":\"conditionSet\",\"identifier\":{\"key\":\"2d02a680-eb7e-4645-bba2-dd298f76efb8\",\"namespace\":\"\"},\"configuration\":{\"conditionTestData\":[],\"conditionCollection\":[{\"isDefault\":true,\"id\":\"4291d80c-303c-4d8d-85e1-10f012b864fb\",\"configuration\":{\"name\":\"Default\",\"output\":\"Default\",\"trigger\":\"all\",\"criteria\":[]},\"summary\":\"Default condition\"}]},\"composition\":[],\"telemetry\":{},\"modified\":1654538965702,\"location\":\"mine\",\"persisted\":1654538965702}}"
},
{
"name": "mct-tree-expanded",
"value": "[]"
}
]
}
]
}

View File

@@ -52,7 +52,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
]);
//Save localStorage for future test execution
await context.storageState({ path: './e2e/tests/recycled_storage.json' });
await context.storageState({ path: './e2e/test-data/recycled_local_storage.json' });
//Set object identifier from url
conditionSetUrl = await page.url();
@@ -65,7 +65,7 @@ test.describe.serial('Condition Set CRUD Operations on @localStorage', () => {
await browser.close();
});
//Load localStorage for subsequent tests
test.use({ storageState: './e2e/tests/recycled_storage.json' });
test.use({ storageState: './e2e/test-data/recycled_local_storage.json' });
//Begin suite of tests again localStorage
test('Condition set object properties persist in main view and inspector', async ({ page }) => {
//Navigate to baseURL with injected localStorage

View File

@@ -0,0 +1,70 @@
/*****************************************************************************
* 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 in a default context. The tests within this suite
are only meant to run against openmct's app.js started by `npm run start` within the
`./e2e/playwright-visual.config.js` file.
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, expect } = require('@playwright/test');
const percySnapshot = require('@percy/playwright');
const path = require('path');
const sinon = require('sinon');
// Snippet from https://github.com/microsoft/playwright/issues/6347#issuecomment-965887758
// Will replace with cy.clock() equivalent
test.beforeEach(async ({ context }) => {
await context.addInitScript({
// eslint-disable-next-line no-undef
path: path.join(__dirname, '../../..', './node_modules/sinon/pkg/sinon.js')
});
await context.addInitScript(() => {
window.__clock = sinon.useFakeTimers({
now: 0, //Set browser clock to UNIX Epoch
shouldAdvanceTime: false, //Don't advance the clock
toFake: ["setTimeout", "nextTick"]
});
});
});
test.use({ storageState: './e2e/test-data/VisualTestData_storage.json' });
test('Visual - Overlay Plot Loading Indicator @localstorage', async ({ page }) => {
// Go to baseURL
await page.goto('/', { waitUntil: 'networkidle' });
await page.locator('a:has-text("Unnamed Overlay Plot Overlay Plot")').click();
//Ensure that we're on the Unnamed Overlay Plot object
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
//Wait for canvas to be rendered and stop animating
await page.locator('canvas >> nth=1').hover({trial: true});
//Take snapshot of Sine Wave Generator within Overlay Plot
await percySnapshot(page, 'SineWaveInOverlayPlot');
});

View File

@@ -0,0 +1,95 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2022, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*
This test suite is dedicated to generating LocalStorage via Session Storage to be used
in some visual test suites like controlledClock.visual.spec.js. This suite should run to completion
and generate an artifact named ./e2e/test-data/VisualTestData_storage.json . This will run
on every Commit to ensure that this object still loads into tests correctly and will retain the
.e2e.spec.js suffix.
TODO: Provide additional validation of object properties as it grows.
*/
const { test } = require('../../fixtures.js');
const { expect } = require('@playwright/test');
test('Generate Visual Test Data @localStorage', async ({ page, context }) => {
//Go to baseURL
await page.goto('/', { waitUntil: 'networkidle' });
await page.locator('button:has-text("Create")').click();
// add overlay plot with defaults
await page.locator('li:has-text("Overlay Plot")').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(),
//Wait for Save Banner to appear1
page.waitForSelector('.c-message-banner__message')
]);
//Wait until Save Banner is gone
await page.locator('.c-message-banner__close-button').click();
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
// save (exit edit mode)
await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click();
await page.locator('text=Save and Finish Editing').click();
// click create button
await page.locator('button:has-text("Create")').click();
// add sine wave generator with defaults
await page.locator('li:has-text("Sine Wave Generator")').click();
//Add a 5000 ms Delay
await page.locator('[aria-label="Loading Delay \\(ms\\)"]').fill('5000');
// Click on My Items in Tree. Workaround for https://github.com/nasa/openmct/issues/5184
await page.click('form[name="mctForm"] a:has-text("Overlay Plot")');
await Promise.all([
page.waitForNavigation(),
page.locator('text=OK').click(),
//Wait for Save Banner to appear1
page.waitForSelector('.c-message-banner__message')
]);
//Wait until Save Banner is gone
await page.locator('.c-message-banner__close-button').click();
await page.waitForSelector('.c-message-banner__message', { state: 'detached'});
// focus the overlay plot
await page.locator('text=Open MCT My Items >> span').nth(3).click();
await Promise.all([
page.waitForNavigation(),
page.locator('text=Unnamed Overlay Plot').first().click()
]);
await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Overlay Plot');
//Save localStorage for future test execution
await context.storageState({ path: './e2e/test-data/VisualTestData_storage.json' });
});

View File

@@ -32,7 +32,8 @@ define([
offset: 0,
dataRateInHz: 1,
randomness: 0,
phase: 0
phase: 0,
loadDelay: 0
};
function GeneratorProvider(openmct) {
@@ -53,8 +54,9 @@ define([
'period',
'offset',
'dataRateInHz',
'randomness',
'phase',
'randomness'
'loadDelay'
];
request = request || {};

View File

@@ -116,6 +116,7 @@
var dataRateInHz = request.dataRateInHz;
var phase = request.phase;
var randomness = request.randomness;
var loadDelay = Math.max(request.loadDelay, 0);
var step = 1000 / dataRateInHz;
var nextStep = start - (start % step) + step;
@@ -133,6 +134,14 @@
});
}
if (loadDelay === 0) {
postOnRequest(message, request, data);
} else {
setTimeout(() => postOnRequest(message, request, data), loadDelay);
}
}
function postOnRequest(message, request, data) {
self.postMessage({
id: message.id,
data: request.spectra ? {

View File

@@ -132,6 +132,17 @@ define([
"telemetry",
"randomness"
]
},
{
name: "Loading Delay (ms)",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "loadDelay",
required: true,
property: [
"telemetry",
"loadDelay"
]
}
],
initialize: function (object) {
@@ -141,7 +152,8 @@ define([
offset: 0,
dataRateInHz: 1,
phase: 0,
randomness: 0
randomness: 0,
loadDelay: 0
};
}
});

View File

@@ -60,6 +60,7 @@
tabindex="0"
:disabled="isInvalid"
class="c-button c-button--major"
aria-label="Save"
@click="onSave"
>
{{ submitLabel }}
@@ -67,6 +68,7 @@
<button
tabindex="0"
class="c-button js-cancel-button"
aria-label="Cancel"
@click="onDismiss"
>
{{ cancelLabel }}

View File

@@ -28,6 +28,7 @@
>
<input
v-model="field"
:aria-label="model.name"
type="number"
:min="model.min"
:max="model.max"

View File

@@ -484,7 +484,7 @@ export default {
end: range.max,
domain: this.config.xAxis.get('key')
})
.then(this.stopLoading());
.then(this.stopLoading.bind(this));
if (purge) {
plotSeries.purgeRecordsOutsideRange(range);
}

View File

@@ -24,16 +24,16 @@
ref="plotWrapper"
class="c-plot holder holder-plot has-control-bar"
>
<div
ref="plotContainer"
class="l-view-section u-style-receiver js-style-receiver"
:class="{'s-status-timeconductor-unsynced': status && status === 'timeconductor-unsynced'}"
>
<div
<progress-bar
v-show="!!loading"
class="c-loading--overlay loading"
></div>
class="c-telemetry-table__progress-bar"
:model="{progressPerc: undefined}"
/>
<mct-plot
:init-grid-lines="gridLines"
:init-cursor-guide="cursorGuide"
@@ -49,10 +49,12 @@
import eventHelpers from './lib/eventHelpers';
import ImageExporter from '../../exporters/ImageExporter';
import MctPlot from './MctPlot.vue';
import ProgressBar from "../../ui/components/ProgressBar.vue";
export default {
components: {
MctPlot
MctPlot,
ProgressBar
},
inject: ['openmct', 'domainObject', 'path'],
props: {
@@ -89,17 +91,14 @@ export default {
destroy() {
this.stopListening();
},
exportJPG() {
const plotElement = this.$refs.plotContainer;
this.imageExporter.exportJPG(plotElement, 'plot.jpg', 'export-plot');
},
exportPNG() {
const plotElement = this.$refs.plotContainer;
this.imageExporter.exportPNG(plotElement, 'plot.png', 'export-plot');
},
setStatus(status) {
this.status = status;
},

View File

@@ -25,6 +25,7 @@
<script>
import MctPlot from '../MctPlot.vue';
import ProgressBar from "../../../ui/components/ProgressBar.vue";
import Vue from "vue";
import conditionalStylesMixin from "./mixins/objectStyles-mixin";
import configStore from "@/plugins/plot/configuration/ConfigStore";
@@ -125,7 +126,6 @@ export default {
const onConfigLoaded = this.onConfigLoaded;
const onCursorGuideChange = this.onCursorGuideChange;
const onGridLinesChange = this.onGridLinesChange;
const loadingUpdated = this.loadingUpdated;
const setStatus = this.setStatus;
const openmct = this.openmct;
@@ -140,7 +140,8 @@ export default {
this.component = new Vue({
el: viewContainer,
components: {
MctPlot
MctPlot,
ProgressBar
},
provide: {
openmct,
@@ -156,11 +157,16 @@ export default {
onConfigLoaded,
onCursorGuideChange,
onGridLinesChange,
loadingUpdated,
setStatus
setStatus,
loading: true
};
},
template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver" :class="{\'s-status-timeconductor-unsynced\': status && status === \'timeconductor-unsynced\'}"><div v-show="!!loading" class="c-loading--overlay loading"></div><mct-plot :init-grid-lines="gridLines" :init-cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :limit-line-labels="limitLineLabels" :color-palette="colorPalette" :options="options" @plotTickWidth="onTickWidthChange" @lockHighlightPoint="onLockHighlightPointUpdated" @highlights="onHighlightsUpdated" @configLoaded="onConfigLoaded" @cursorGuide="onCursorGuideChange" @gridLines="onGridLinesChange" @statusUpdated="setStatus" @loadingUpdated="loadingUpdated"/></div>'
methods: {
loadingUpdated(loaded) {
this.loading = loaded;
},
},
template: '<div ref="plotWrapper" class="l-view-section u-style-receiver js-style-receiver" :class="{\'s-status-timeconductor-unsynced\': status && status === \'timeconductor-unsynced\'}"><progress-bar v-show="loading !== false" class="c-telemetry-table__progress-bar" :model="{progressPerc: undefined}" /><mct-plot :init-grid-lines="gridLines" :init-cursor-guide="cursorGuide" :plot-tick-width="plotTickWidth" :options="options" @plotTickWidth="onTickWidthChange" @cursorGuide="onCursorGuideChange" @gridLines="onGridLinesChange" @statusUpdated="setStatus" @loadingUpdated="loadingUpdated"/></div>'
});
this.setSelection();
@@ -198,17 +204,12 @@ export default {
this.removeSelectable = this.openmct.selection.selectable(
this.$el, this.context);
},
loadingUpdated(loaded) {
this.loading = loaded;
this.updateComponentProp('loading', loaded);
},
getProps() {
return {
limitLineLabels: this.showLimitLineLabels,
gridLines: this.gridLines,
cursorGuide: this.cursorGuide,
plotTickWidth: this.plotTickWidth,
loading: this.loading,
options: this.options,
status: this.status,
colorPalette: this.colorPalette

View File

@@ -144,7 +144,7 @@
<progress-bar
v-if="loading"
class="c-telemetry-table__progress-bar"
:model="progressLoad"
:model="{progressPerc: undefined}"
/>
<!-- Headers table -->
@@ -385,11 +385,6 @@ export default {
};
},
computed: {
progressLoad() {
return {
progressPerc: undefined
};
},
dropTargetStyle() {
return {
top: this.$refs.headersTable.offsetTop + 'px',