mirror of
https://github.com/nasa/openmct.git
synced 2025-02-21 17:57:04 +00:00
2.1.0 backmerge into master (#5784)
* Update version * [Flexible Layout] Fix draggable status for layout items while in browse mode (#5750) * Modify flexible layout pages to make them not draggable in browse mode and add e2e test * Don't destroy mutable if the domain object is not ready yet (#5695) * Check if the domain object is set (mounted is done) before trying to destroy the mutable * Use optional chaining. Add mutable promise check to prevent memory leaks * Request priority (#5737) * Set priority of couch requests to high * Set priority of image requests to low * Add e2e test for low-priority images * Timelist views support fixed time - 5629 (#5726) * Initialize full view for fixed time * Clean up * Add back in ticker after merge * Check for undefined clock instead of timestamp * Cleanup * Initialize full view for fixed time * Clean up * Add back in ticker after merge * Check for undefined clock instead of timestamp * Cleanup * Update timestamp method and remove from beforeDestroy * Shorten ternary to optional chaining * Cleanup unused var * Moved duplicated logic to method * Reorder methods * Update Timelist.vue Set timestamp to clock start when in fixed time * Added blank line * Lint fix * Update pluginSpec.js * Invoke currentValue method properly Co-authored-by: Khalid Adil <khalidadil29@gmail.com> Co-authored-by: Andrew Henry <akhenry@gmail.com> Co-authored-by: Michael Rogers <contact@mhrogers.com>
This commit is contained in:
parent
07bf85a623
commit
f39419bc84
@ -0,0 +1,66 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2022, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
|
test.describe('Testing Flexible Layout @unstable', () => {
|
||||||
|
test.beforeEach(async ({ page }) => {
|
||||||
|
await page.goto('./', { waitUntil: 'networkidle' });
|
||||||
|
|
||||||
|
// Create Sine Wave Generator
|
||||||
|
await createDomainObjectWithDefaults(page, {
|
||||||
|
type: 'Sine Wave Generator',
|
||||||
|
name: "Test Sine Wave Generator"
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create Clock Object
|
||||||
|
await createDomainObjectWithDefaults(page, {
|
||||||
|
type: 'Clock',
|
||||||
|
name: "Test Clock"
|
||||||
|
});
|
||||||
|
});
|
||||||
|
test('panes have the appropriate draggable attribute while in Edit and Browse modes', async ({ page }) => {
|
||||||
|
// Create a Flexible Layout
|
||||||
|
await createDomainObjectWithDefaults(page, {
|
||||||
|
type: 'Flexible Layout',
|
||||||
|
name: "Test Flexible Layout"
|
||||||
|
});
|
||||||
|
// Edit Flexible Layout
|
||||||
|
await page.locator('[title="Edit"]').click();
|
||||||
|
|
||||||
|
// Expand the 'My Items' folder in the left tree
|
||||||
|
await page.locator('.c-tree__item__view-control.c-disclosure-triangle').first().click();
|
||||||
|
// Add the Sine Wave Generator and Clock to the Flexible Layout
|
||||||
|
await page.dragAndDrop('text=Test Sine Wave Generator', '.c-fl__container.is-empty');
|
||||||
|
await page.dragAndDrop('text=Test Clock', '.c-fl__container.is-empty');
|
||||||
|
// Check that panes can be dragged while Flexible Layout is in Edit mode
|
||||||
|
let dragWrapper = await page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||||
|
await expect(dragWrapper).toHaveAttribute('draggable', 'true');
|
||||||
|
// Save Flexible Layout
|
||||||
|
await page.locator('button[title="Save"]').click();
|
||||||
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
|
// Check that panes are not draggable while Flexible Layout is in Browse mode
|
||||||
|
dragWrapper = await page.locator('.c-fl-container__frames-holder .c-fl-frame__drag-wrapper').first();
|
||||||
|
await expect(dragWrapper).toHaveAttribute('draggable', 'false');
|
||||||
|
});
|
||||||
|
});
|
@ -167,6 +167,11 @@ test.describe('Example Imagery Object', () => {
|
|||||||
await zoomIntoImageryByButton(page);
|
await zoomIntoImageryByButton(page);
|
||||||
await expect(pausePlayButton).not.toHaveClass(/is-paused/);
|
await expect(pausePlayButton).not.toHaveClass(/is-paused/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Uses low fetch priority', async ({ page }) => {
|
||||||
|
const priority = await page.locator('.js-imageryView-image').getAttribute('fetchpriority');
|
||||||
|
await expect(priority).toBe('low');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('Example Imagery in Display Layout', () => {
|
test.describe('Example Imagery in Display Layout', () => {
|
||||||
|
@ -147,7 +147,7 @@ export default {
|
|||||||
this.mutablePromise.then(() => {
|
this.mutablePromise.then(() => {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
});
|
});
|
||||||
} else if (this.domainObject.isMutable) {
|
} else if (this?.domainObject?.isMutable) {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -243,7 +243,7 @@ export default {
|
|||||||
this.mutablePromise.then(() => {
|
this.mutablePromise.then(() => {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
});
|
});
|
||||||
} else if (this.domainObject.isMutable) {
|
} else if (this?.domainObject?.isMutable) {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -281,6 +281,10 @@ export default {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.isEditing) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let containerId = event.dataTransfer.getData('containerid');
|
let containerId = event.dataTransfer.getData('containerid');
|
||||||
let container = this.containers.filter((c) => c.id === containerId)[0];
|
let container = this.containers.filter((c) => c.id === containerId)[0];
|
||||||
let containerPos = this.containers.indexOf(container);
|
let containerPos = this.containers.indexOf(container);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<div
|
<div
|
||||||
ref="frame"
|
ref="frame"
|
||||||
class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
||||||
draggable="true"
|
:draggable="draggable"
|
||||||
@dragstart="initDrag"
|
@dragstart="initDrag"
|
||||||
>
|
>
|
||||||
<object-frame
|
<object-frame
|
||||||
@ -93,18 +93,20 @@ export default {
|
|||||||
computed: {
|
computed: {
|
||||||
hasFrame() {
|
hasFrame() {
|
||||||
return !this.frame.noFrame;
|
return !this.frame.noFrame;
|
||||||
|
},
|
||||||
|
draggable() {
|
||||||
|
return this.isEditing;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.frame.domainObjectIdentifier) {
|
if (this.frame.domainObjectIdentifier) {
|
||||||
let domainObjectPromise;
|
|
||||||
if (this.openmct.objects.supportsMutation(this.frame.domainObjectIdentifier)) {
|
if (this.openmct.objects.supportsMutation(this.frame.domainObjectIdentifier)) {
|
||||||
domainObjectPromise = this.openmct.objects.getMutable(this.frame.domainObjectIdentifier);
|
this.domainObjectPromise = this.openmct.objects.getMutable(this.frame.domainObjectIdentifier);
|
||||||
} else {
|
} else {
|
||||||
domainObjectPromise = this.openmct.objects.get(this.frame.domainObjectIdentifier);
|
this.domainObjectPromise = this.openmct.objects.get(this.frame.domainObjectIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
domainObjectPromise.then((object) => {
|
this.domainObjectPromise.then((object) => {
|
||||||
this.setDomainObject(object);
|
this.setDomainObject(object);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -112,7 +114,13 @@ export default {
|
|||||||
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.domainObject.isMutable) {
|
if (this.domainObjectPromise) {
|
||||||
|
this.domainObjectPromise.then(() => {
|
||||||
|
if (this?.domainObject?.isMutable) {
|
||||||
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (this?.domainObject?.isMutable) {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@
|
|||||||
<img
|
<img
|
||||||
class="c-thumb__image"
|
class="c-thumb__image"
|
||||||
:src="image.url"
|
:src="image.url"
|
||||||
|
fetchpriority="low"
|
||||||
>
|
>
|
||||||
</a>
|
</a>
|
||||||
<div class="c-thumb__timestamp">{{ image.formattedTime }}</div>
|
<div class="c-thumb__timestamp">{{ image.formattedTime }}</div>
|
||||||
|
@ -82,6 +82,7 @@
|
|||||||
}"
|
}"
|
||||||
:data-openmct-image-timestamp="time"
|
:data-openmct-image-timestamp="time"
|
||||||
:data-openmct-object-keystring="keyString"
|
:data-openmct-object-keystring="keyString"
|
||||||
|
fetchpriority="low"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="imageUrl"
|
v-if="imageUrl"
|
||||||
|
@ -187,6 +187,7 @@ class CouchObjectProvider {
|
|||||||
let fetchOptions = {
|
let fetchOptions = {
|
||||||
method,
|
method,
|
||||||
body,
|
body,
|
||||||
|
priority: 'high',
|
||||||
signal
|
signal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -109,6 +109,12 @@ describe('the plugin', () => {
|
|||||||
expect(result.identifier.key).toEqual(mockDomainObject.identifier.key);
|
expect(result.identifier.key).toEqual(mockDomainObject.identifier.key);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('prioritizes couch requests above other requests', async () => {
|
||||||
|
await openmct.objects.get(mockDomainObject.identifier);
|
||||||
|
const fetchOptions = fetch.calls.mostRecent().args[1];
|
||||||
|
expect(fetchOptions.priority).toEqual('high');
|
||||||
|
});
|
||||||
|
|
||||||
it('creates an object and starts shared worker', async () => {
|
it('creates an object and starts shared worker', async () => {
|
||||||
const result = await openmct.objects.save(mockDomainObject);
|
const result = await openmct.objects.save(mockDomainObject);
|
||||||
expect(provider.create).toHaveBeenCalled();
|
expect(provider.create).toHaveBeenCalled();
|
||||||
|
@ -92,7 +92,7 @@ export default {
|
|||||||
this.mutablePromise.then(() => {
|
this.mutablePromise.then(() => {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
});
|
});
|
||||||
} else if (this.domainObject.isMutable) {
|
} else if (this?.domainObject?.isMutable) {
|
||||||
this.openmct.objects.destroyMutable(this.domainObject);
|
this.openmct.objects.destroyMutable(this.domainObject);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -110,7 +110,9 @@ export default {
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.isEditing = this.openmct.editor.isEditing();
|
this.isEditing = this.openmct.editor.isEditing();
|
||||||
this.timestamp = Date.now();
|
this.timestamp = this.openmct.time.clock()?.currentValue() || this.openmct.time.bounds()?.start;
|
||||||
|
this.openmct.time.on('clock', this.setViewFromClock);
|
||||||
|
|
||||||
this.getPlanDataAndSetConfig(this.domainObject);
|
this.getPlanDataAndSetConfig(this.domainObject);
|
||||||
|
|
||||||
this.unlisten = this.openmct.objects.observe(this.domainObject, 'selectFile', this.planFileUpdated);
|
this.unlisten = this.openmct.objects.observe(this.domainObject, 'selectFile', this.planFileUpdated);
|
||||||
@ -118,6 +120,7 @@ export default {
|
|||||||
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
||||||
this.status = this.openmct.status.get(this.domainObject.identifier);
|
this.status = this.openmct.status.get(this.domainObject.identifier);
|
||||||
this.unlistenTicker = ticker.listen(this.clearPreviousActivities);
|
this.unlistenTicker = ticker.listen(this.clearPreviousActivities);
|
||||||
|
this.openmct.time.on('bounds', this.updateTimestamp);
|
||||||
this.openmct.editor.on('isEditing', this.setEditState);
|
this.openmct.editor.on('isEditing', this.setEditState);
|
||||||
|
|
||||||
this.deferAutoScroll = _.debounce(this.deferAutoScroll, 500);
|
this.deferAutoScroll = _.debounce(this.deferAutoScroll, 500);
|
||||||
@ -128,6 +131,9 @@ export default {
|
|||||||
this.composition.on('remove', this.removeItem);
|
this.composition.on('remove', this.removeItem);
|
||||||
this.composition.load();
|
this.composition.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.setViewFromClock(this.openmct.time.clock());
|
||||||
|
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.unlisten) {
|
if (this.unlisten) {
|
||||||
@ -147,6 +153,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.openmct.editor.off('isEditing', this.setEditState);
|
this.openmct.editor.off('isEditing', this.setEditState);
|
||||||
|
this.openmct.time.off('bounds', this.updateTimestamp);
|
||||||
|
this.openmct.time.off('clock', this.setViewFromClock);
|
||||||
|
|
||||||
this.$el.parentElement.removeEventListener('scroll', this.deferAutoScroll, true);
|
this.$el.parentElement.removeEventListener('scroll', this.deferAutoScroll, true);
|
||||||
if (this.clearAutoScrollDisabledTimer) {
|
if (this.clearAutoScrollDisabledTimer) {
|
||||||
@ -176,12 +184,32 @@ export default {
|
|||||||
this.showAll = true;
|
this.showAll = true;
|
||||||
this.listActivities();
|
this.listActivities();
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
this.filterValue = configuration.filter;
|
this.filterValue = configuration.filter;
|
||||||
this.setSort();
|
this.setSort();
|
||||||
this.setViewBounds();
|
this.setViewBounds();
|
||||||
this.listActivities();
|
this.listActivities();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
updateTimestamp(_bounds, isTick) {
|
||||||
|
if (isTick === true) {
|
||||||
|
this.timestamp = this.openmct.time.clock().currentValue();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setViewFromClock(newClock) {
|
||||||
|
this.filterValue = this.domainObject.configuration.filter;
|
||||||
|
const isFixedTime = newClock === undefined;
|
||||||
|
if (isFixedTime) {
|
||||||
|
this.hideAll = false;
|
||||||
|
this.showAll = true;
|
||||||
|
// clear invokes listActivities
|
||||||
|
this.clearPreviousActivities(this.openmct.time.bounds()?.start);
|
||||||
|
} else {
|
||||||
|
this.setSort();
|
||||||
|
this.setViewBounds();
|
||||||
|
this.listActivities();
|
||||||
|
}
|
||||||
|
},
|
||||||
addItem(domainObject) {
|
addItem(domainObject) {
|
||||||
this.planObjects = [domainObject];
|
this.planObjects = [domainObject];
|
||||||
this.resetPlanData();
|
this.resetPlanData();
|
||||||
@ -400,7 +428,7 @@ export default {
|
|||||||
|
|
||||||
this.firstCurrentActivityIndex = -1;
|
this.firstCurrentActivityIndex = -1;
|
||||||
this.currentActivitiesCount = 0;
|
this.currentActivitiesCount = 0;
|
||||||
this.$el.parentElement.scrollTo({top: 0});
|
this.$el.parentElement?.scrollTo({top: 0});
|
||||||
this.autoScrolled = false;
|
this.autoScrolled = false;
|
||||||
},
|
},
|
||||||
setScrollTop() {
|
setScrollTop() {
|
||||||
|
@ -376,7 +376,7 @@ describe('the plugin', function () {
|
|||||||
|
|
||||||
return Vue.nextTick(() => {
|
return Vue.nextTick(() => {
|
||||||
const items = element.querySelectorAll(LIST_ITEM_CLASS);
|
const items = element.querySelectorAll(LIST_ITEM_CLASS);
|
||||||
expect(items.length).toEqual(1);
|
expect(items.length).toEqual(2);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user