mirror of
https://github.com/nasa/openmct.git
synced 2025-02-20 17:33:23 +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 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', () => {
|
||||
|
@ -147,7 +147,7 @@ export default {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this.domainObject.isMutable) {
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
|
@ -243,7 +243,7 @@ export default {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this.domainObject.isMutable) {
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
|
@ -281,6 +281,10 @@ export default {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.isEditing) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let containerId = event.dataTransfer.getData('containerid');
|
||||
let container = this.containers.filter((c) => c.id === containerId)[0];
|
||||
let containerPos = this.containers.indexOf(container);
|
||||
|
@ -31,7 +31,7 @@
|
||||
<div
|
||||
ref="frame"
|
||||
class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
||||
draggable="true"
|
||||
:draggable="draggable"
|
||||
@dragstart="initDrag"
|
||||
>
|
||||
<object-frame
|
||||
@ -93,18 +93,20 @@ export default {
|
||||
computed: {
|
||||
hasFrame() {
|
||||
return !this.frame.noFrame;
|
||||
},
|
||||
draggable() {
|
||||
return this.isEditing;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (this.frame.domainObjectIdentifier) {
|
||||
let domainObjectPromise;
|
||||
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 {
|
||||
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);
|
||||
});
|
||||
}
|
||||
@ -112,7 +114,13 @@ export default {
|
||||
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||
},
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
<img
|
||||
class="c-thumb__image"
|
||||
:src="image.url"
|
||||
fetchpriority="low"
|
||||
>
|
||||
</a>
|
||||
<div class="c-thumb__timestamp">{{ image.formattedTime }}</div>
|
||||
|
@ -82,6 +82,7 @@
|
||||
}"
|
||||
:data-openmct-image-timestamp="time"
|
||||
:data-openmct-object-keystring="keyString"
|
||||
fetchpriority="low"
|
||||
>
|
||||
<div
|
||||
v-if="imageUrl"
|
||||
|
@ -187,6 +187,7 @@ class CouchObjectProvider {
|
||||
let fetchOptions = {
|
||||
method,
|
||||
body,
|
||||
priority: 'high',
|
||||
signal
|
||||
};
|
||||
|
||||
|
@ -109,6 +109,12 @@ describe('the plugin', () => {
|
||||
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 () => {
|
||||
const result = await openmct.objects.save(mockDomainObject);
|
||||
expect(provider.create).toHaveBeenCalled();
|
||||
|
@ -92,7 +92,7 @@ export default {
|
||||
this.mutablePromise.then(() => {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
});
|
||||
} else if (this.domainObject.isMutable) {
|
||||
} else if (this?.domainObject?.isMutable) {
|
||||
this.openmct.objects.destroyMutable(this.domainObject);
|
||||
}
|
||||
},
|
||||
|
@ -110,7 +110,9 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
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.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.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);
|
||||
|
||||
this.deferAutoScroll = _.debounce(this.deferAutoScroll, 500);
|
||||
@ -128,6 +131,9 @@ export default {
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
this.setViewFromClock(this.openmct.time.clock());
|
||||
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (this.unlisten) {
|
||||
@ -147,6 +153,8 @@ export default {
|
||||
}
|
||||
|
||||
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);
|
||||
if (this.clearAutoScrollDisabledTimer) {
|
||||
@ -176,12 +184,32 @@ export default {
|
||||
this.showAll = true;
|
||||
this.listActivities();
|
||||
} else {
|
||||
|
||||
this.filterValue = configuration.filter;
|
||||
this.setSort();
|
||||
this.setViewBounds();
|
||||
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) {
|
||||
this.planObjects = [domainObject];
|
||||
this.resetPlanData();
|
||||
@ -400,7 +428,7 @@ export default {
|
||||
|
||||
this.firstCurrentActivityIndex = -1;
|
||||
this.currentActivitiesCount = 0;
|
||||
this.$el.parentElement.scrollTo({top: 0});
|
||||
this.$el.parentElement?.scrollTo({top: 0});
|
||||
this.autoScrolled = false;
|
||||
},
|
||||
setScrollTop() {
|
||||
|
@ -376,7 +376,7 @@ describe('the plugin', function () {
|
||||
|
||||
return Vue.nextTick(() => {
|
||||
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