Use different root for renderWhenVisible (#7415)

* attempt to fix

* reenable test

* going to revert most of this, but works

* slowly reverting changes

* further reversions to the mean

* reversion to the mean

* revert

* change to use openmct element

* reference issue

* reference issue

---------

Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
Scott Bell 2024-01-30 00:33:47 +01:00 committed by GitHub
parent 5c21c34568
commit f8d936a834
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 78 additions and 64 deletions

View File

@ -63,80 +63,78 @@ test.describe('Overlay Plot', () => {
await expect(seriesColorSwatch).toHaveCSS('background-color', 'rgb(255, 166, 61)'); await expect(seriesColorSwatch).toHaveCSS('background-color', 'rgb(255, 166, 61)');
}); });
//skipping due to https://github.com/nasa/openmct/issues/7405 test('Limit lines persist when series is moved to another Y Axis and on refresh', async ({
test.fixme( page
'Limit lines persist when series is moved to another Y Axis and on refresh', }) => {
async ({ page }) => { test.info().annotations.push({
test.info().annotations.push({ type: 'issue',
type: 'issue', description: 'https://github.com/nasa/openmct/issues/6338'
description: 'https://github.com/nasa/openmct/issues/6338' });
}); // Create an Overlay Plot with a default SWG
// Create an Overlay Plot with a default SWG const overlayPlot = await createDomainObjectWithDefaults(page, {
const overlayPlot = await createDomainObjectWithDefaults(page, { type: 'Overlay Plot'
type: 'Overlay Plot' });
});
const swgA = await createDomainObjectWithDefaults(page, { const swgA = await createDomainObjectWithDefaults(page, {
type: 'Sine Wave Generator', type: 'Sine Wave Generator',
parent: overlayPlot.uuid parent: overlayPlot.uuid
}); });
await page.goto(overlayPlot.url); await page.goto(overlayPlot.url);
// Assert that no limit lines are shown by default // Assert that no limit lines are shown by default
await page.waitForSelector('.js-limit-area', { state: 'attached' }); await page.waitForSelector('.js-limit-area', { state: 'attached' });
expect(await page.locator('.c-plot-limit-line').count()).toBe(0); expect(await page.locator('.c-plot-limit-line').count()).toBe(0);
// Enter edit mode // Enter edit mode
await page.getByLabel('Edit Object').click(); await page.getByLabel('Edit Object').click();
// Expand the "Sine Wave Generator" plot series options and enable limit lines // Expand the "Sine Wave Generator" plot series options and enable limit lines
await page.getByRole('tab', { name: 'Config' }).click(); await page.getByRole('tab', { name: 'Config' }).click();
await page await page
.getByRole('list', { name: 'Plot Series Properties' }) .getByRole('list', { name: 'Plot Series Properties' })
.locator('span') .locator('span')
.first() .first()
.click(); .click();
await page await page
.getByRole('list', { name: 'Plot Series Properties' }) .getByRole('list', { name: 'Plot Series Properties' })
.locator('[title="Display limit lines"]~div input') .locator('[title="Display limit lines"]~div input')
.check(); .check();
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
// Save (exit edit mode) // Save (exit edit mode)
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
await page.reload(); await page.reload();
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
// Enter edit mode // Enter edit mode
await page.getByLabel('Edit Object').click(); await page.getByLabel('Edit Object').click();
await page.getByRole('tab', { name: 'Elements' }).click(); await page.getByRole('tab', { name: 'Elements' }).click();
// Drag Sine Wave Generator series from Y Axis 1 into Y Axis 2 // Drag Sine Wave Generator series from Y Axis 1 into Y Axis 2
await page await page
.locator(`#inspector-elements-tree >> text=${swgA.name}`) .locator(`#inspector-elements-tree >> text=${swgA.name}`)
.dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]')); .dragTo(page.locator('[aria-label="Element Item Group Y Axis 2"]'));
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
// Save (exit edit mode) // Save (exit edit mode)
await page.locator('button[title="Save"]').click(); await page.locator('button[title="Save"]').click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click(); await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
await page.reload(); await page.reload();
await assertLimitLinesExistAndAreVisible(page); await assertLimitLinesExistAndAreVisible(page);
} });
);
test('The elements pool supports dragging series into multiple y-axis buckets', async ({ test('The elements pool supports dragging series into multiple y-axis buckets', async ({
page page

View File

@ -112,7 +112,7 @@ export default {
}, },
renderPlot(plotObject) { renderPlot(plotObject) {
const wrapper = document.createElement('div'); const wrapper = document.createElement('div');
const visibilityObserver = new VisibilityObserver(wrapper); const visibilityObserver = new VisibilityObserver(wrapper, this.openmct.element);
const { destroy } = mount( const { destroy } = mount(
{ {

View File

@ -200,7 +200,13 @@ export default {
this.chartVisible = true; this.chartVisible = true;
this.chartContainer = this.$refs.chart; this.chartContainer = this.$refs.chart;
this.drawnOnce = false; this.drawnOnce = false;
this.visibilityObserver = new IntersectionObserver(this.visibilityChanged); const rootContainer = this.openmct.element;
const options = {
root: rootContainer,
rootMargin: '0px',
threshold: 1.0
};
this.visibilityObserver = new IntersectionObserver(this.visibilityChanged, options);
eventHelpers.extend(this); eventHelpers.extend(this);
this.seriesModels = []; this.seriesModels = [];
this.config = this.getConfig(); this.config = this.getConfig();
@ -276,6 +282,8 @@ export default {
return config; return config;
}, },
visibilityChanged([entry]) { visibilityChanged([entry]) {
// Per https://github.com/nasa/openmct/issues/7405, we only want to draw when the chart is visible.
// and we need to use the Open MCT root element as the root of the intersection observer.
if (entry.target === this.chartContainer) { if (entry.target === this.chartContainer) {
const wasVisible = this.chartVisible; const wasVisible = this.chartVisible;
this.chartVisible = entry.isIntersecting; this.chartVisible = entry.isIntersecting;

View File

@ -131,7 +131,10 @@ export default {
this.debounceUpdateView = _.debounce(this.updateView, 10); this.debounceUpdateView = _.debounce(this.updateView, 10);
}, },
mounted() { mounted() {
this.visibilityObserver = new VisibilityObserver(this.$refs.objectViewWrapper); this.visibilityObserver = new VisibilityObserver(
this.$refs.objectViewWrapper,
this.openmct.element
);
this.updateView(); this.updateView();
this.$refs.objectViewWrapper.addEventListener('dragover', this.onDragOver, { this.$refs.objectViewWrapper.addEventListener('dragover', this.onDragOver, {
capture: true capture: true

View File

@ -32,17 +32,22 @@ export default class VisibilityObserver {
* Constructs a VisibilityObserver instance to manage visibility-based requestAnimationFrame calls. * Constructs a VisibilityObserver instance to manage visibility-based requestAnimationFrame calls.
* *
* @param {HTMLElement} element - The DOM element to observe for visibility changes. * @param {HTMLElement} element - The DOM element to observe for visibility changes.
* @param {HTMLElement} rootContainer - The DOM element that is the root of the viewport.
* @throws {Error} If element is not provided. * @throws {Error} If element is not provided.
*/ */
constructor(element) { constructor(element, rootContainer) {
if (!element) { if (!element || !rootContainer) {
throw new Error(`VisibilityObserver must be created with an element`); throw new Error(`VisibilityObserver must be created with an element and a rootContainer.`);
} }
this.#element = element; this.#element = element;
this.isIntersecting = true; this.isIntersecting = true;
this.calledOnce = false; this.calledOnce = false;
const options = {
this.#observer = new IntersectionObserver(this.#observerCallback); root: rootContainer,
rootMargin: '0px',
threshold: 1.0
};
this.#observer = new IntersectionObserver(this.#observerCallback, options);
this.lastUnfiredFunc = null; this.lastUnfiredFunc = null;
this.renderWhenVisible = this.renderWhenVisible.bind(this); this.renderWhenVisible = this.renderWhenVisible.bind(this);
} }