diff --git a/e2e/tests/functional/plugins/flexibleLayout/flexibleLayout.e2e.spec.js b/e2e/tests/functional/plugins/flexibleLayout/flexibleLayout.e2e.spec.js new file mode 100644 index 00000000000..484091d7ce0 --- /dev/null +++ b/e2e/tests/functional/plugins/flexibleLayout/flexibleLayout.e2e.spec.js @@ -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'); + }); +}); diff --git a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js index b24e511852f..f399daee010 100644 --- a/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js +++ b/e2e/tests/functional/plugins/imagery/exampleImagery.e2e.spec.js @@ -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', () => { diff --git a/src/plugins/displayLayout/components/SubobjectView.vue b/src/plugins/displayLayout/components/SubobjectView.vue index 8e58f89ddd2..0e0a0ea6593 100644 --- a/src/plugins/displayLayout/components/SubobjectView.vue +++ b/src/plugins/displayLayout/components/SubobjectView.vue @@ -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); } }, diff --git a/src/plugins/displayLayout/components/TelemetryView.vue b/src/plugins/displayLayout/components/TelemetryView.vue index 19036b26e22..8ae30d91303 100644 --- a/src/plugins/displayLayout/components/TelemetryView.vue +++ b/src/plugins/displayLayout/components/TelemetryView.vue @@ -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); } }, diff --git a/src/plugins/flexibleLayout/components/flexibleLayout.vue b/src/plugins/flexibleLayout/components/flexibleLayout.vue index 503db9a1fc1..c2f8958deec 100644 --- a/src/plugins/flexibleLayout/components/flexibleLayout.vue +++ b/src/plugins/flexibleLayout/components/flexibleLayout.vue @@ -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); diff --git a/src/plugins/flexibleLayout/components/frame.vue b/src/plugins/flexibleLayout/components/frame.vue index 70e6802a631..8515e718b4a 100644 --- a/src/plugins/flexibleLayout/components/frame.vue +++ b/src/plugins/flexibleLayout/components/frame.vue @@ -31,7 +31,7 @@
{ + 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); } diff --git a/src/plugins/imagery/components/ImageThumbnail.vue b/src/plugins/imagery/components/ImageThumbnail.vue index 17016527e78..87eda1fc179 100644 --- a/src/plugins/imagery/components/ImageThumbnail.vue +++ b/src/plugins/imagery/components/ImageThumbnail.vue @@ -38,6 +38,7 @@
{{ image.formattedTime }}
diff --git a/src/plugins/imagery/components/ImageryView.vue b/src/plugins/imagery/components/ImageryView.vue index b6bed994b52..f9a5dfb4c37 100644 --- a/src/plugins/imagery/components/ImageryView.vue +++ b/src/plugins/imagery/components/ImageryView.vue @@ -82,6 +82,7 @@ }" :data-openmct-image-timestamp="time" :data-openmct-object-keystring="keyString" + fetchpriority="low" >
{ 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(); diff --git a/src/plugins/timeline/TimelineObjectView.vue b/src/plugins/timeline/TimelineObjectView.vue index 516d5650fc4..2d1caf1b04d 100644 --- a/src/plugins/timeline/TimelineObjectView.vue +++ b/src/plugins/timeline/TimelineObjectView.vue @@ -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); } }, diff --git a/src/plugins/timelist/Timelist.vue b/src/plugins/timelist/Timelist.vue index 0e655994133..fdbf96e7a37 100644 --- a/src/plugins/timelist/Timelist.vue +++ b/src/plugins/timelist/Timelist.vue @@ -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() { diff --git a/src/plugins/timelist/pluginSpec.js b/src/plugins/timelist/pluginSpec.js index a7bc9e2e39b..1a19b69eeab 100644 --- a/src/plugins/timelist/pluginSpec.js +++ b/src/plugins/timelist/pluginSpec.js @@ -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); }); }); });