fix(#7338): Persisted styles correctly apply to StackedPlotItems on mount (#7341)

* refactor: use `Plot` component directly in `StackedPlotItem` template

* test(e2e): fix style test for stackedplot

* test(e2e): add annotation back in

* test: fix unit tests

* refactor: tidy up

* fix: move const, remove eslint ignore

* fix: apply staleness styling properly

* refactor: remove unused data()

* refactor: remove unused `isMissing`

* refactor: remove debug statements
This commit is contained in:
Jesse Mazzella 2024-01-08 10:19:41 -08:00 committed by GitHub
parent 70de7363d8
commit dfba4e23c5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 216 deletions

View File

@ -38,10 +38,10 @@ const setBackgroundColor = '#5b0f00';
const setTextColor = '#e6b8af';
const defaultTextColor = '#aaaaaa'; // default text color
const NO_STYLE_RGBA = 'rgba(0, 0, 0, 0)'; //default background color value
const DEFAULT_PLOT_VIEW_BORDER_COLOR = '#AAAAAA';
const setFontSize = '72px';
const setFontWeight = '700'; //bold for monospace bold
// eslint-disable-next-line prettier/prettier
const setFontFamily = "\"Andale Mono\", sans-serif";
const setFontFamily = '"Andale Mono", sans-serif';
test.describe('Stacked Plot styling', () => {
let stackedPlot;
@ -156,91 +156,90 @@ test.describe('Stacked Plot styling', () => {
);
});
test.fixme(
'styling a child object of the flexible layout properly applies that style to only that child',
async ({ page }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/7338'
});
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
test('styling a child object of the flexible layout properly applies that style to only that child', async ({
page
}) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/7338'
});
await page.goto(stackedPlot.url, { waitUntil: 'domcontentloaded' });
await page.getByLabel('Edit').click();
await page.getByLabel('Edit').click();
await page.getByRole('tab', { name: 'Styles' }).click();
await page.getByRole('tab', { name: 'Styles' }).click();
//Check default styles for SWG1 and SWG2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
//Check default styles for SWG1 and SWG2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
// Set styles using setStyles function on StackedPlot1 but not StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
// Set styles using setStyles function on StackedPlot1 but not StackedPlot2
await setStyles(
page,
setBorderColor,
setBackgroundColor,
setTextColor,
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
//Set Font Styles on SWG1 but not SWG2
await page.getByLabel('Stacked Plot Item Sine Wave Generator 1').click();
//Set Font Size to 72
await page.getByLabel('Set Font Size').click();
await page.getByRole('menuitem', { name: '72px' }).click();
//Set Font Styles on SWG1 but not SWG2
await page.getByLabel('Stacked Plot Item Sine Wave Generator 1').click();
//Set Font Size to 72
await page.getByLabel('Set Font Size').click();
await page.getByRole('menuitem', { name: '72px' }).click();
//Set Font Type to Monospace Bold. See setFontWeight and setFontFamily variables
await page.getByLabel('Set Font Type').click();
await page.getByRole('menuitem', { name: 'Monospace Bold' }).click();
//Set Font Type to Monospace Bold. See setFontWeight and setFontFamily variables
await page.getByLabel('Set Font Type').click();
await page.getByRole('menuitem', { name: 'Monospace Bold' }).click();
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Save Flexible Layout
await page.getByRole('button', { name: 'Save' }).click();
await page.getByRole('listitem', { name: 'Save and Finish Editing' }).click();
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Plot Container Style Target').first()
);
// Check styles on StackedPlot2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(DEFAULT_PLOT_VIEW_BORDER_COLOR),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Plot Container Style Target').nth(1)
);
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Reload page and verify that styles persist
await page.reload({ waitUntil: 'domcontentloaded' });
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 1')
);
// Check styles on StackedPlot1
await checkStyles(
hexToRGB(setBorderColor),
hexToRGB(setBackgroundColor),
hexToRGB(setTextColor),
page.getByLabel('Plot Container Style Target').first()
);
// Check styles on StackedPlot2
await checkStyles(
NO_STYLE_RGBA,
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Stacked Plot Item Sine Wave Generator 2')
);
}
);
// Check styles on StackedPlot2
await checkStyles(
hexToRGB(DEFAULT_PLOT_VIEW_BORDER_COLOR),
NO_STYLE_RGBA,
hexToRGB(defaultTextColor),
page.getByLabel('Plot Container Style Target').nth(1)
);
});
});

View File

@ -20,11 +20,18 @@
at runtime from the About dialog for additional information.
-->
<template>
<div ref="plotWrapper" class="c-plot holder holder-plot has-control-bar" :class="staleClass">
<div
ref="plotWrapper"
class="c-plot holder holder-plot has-control-bar"
:class="isStale && 'is-stale'"
>
<div
ref="plotContainer"
class="l-view-section u-style-receiver js-style-receiver"
:class="{ 's-status-timeconductor-unsynced': status && status === 'timeconductor-unsynced' }"
aria-label="Plot Container Style Target"
:class="{
's-status-timeconductor-unsynced': status === 'timeconductor-unsynced'
}"
>
<progress-bar
v-show="!!loading"
@ -78,7 +85,7 @@ export default {
PlotLegend
},
mixins: [stalenessMixin],
inject: ['openmct', 'domainObject', 'path'],
inject: ['openmct', 'domainObject'],
props: {
options: {
type: Object,
@ -157,9 +164,6 @@ export default {
gridLinesProp() {
return this.gridLines ?? !this.options.compact;
},
staleClass() {
return this.isStale ? 'is-stale' : '';
},
plotLegendPositionClass() {
return this.position ? `plot-legend-${this.position}` : '';
},

View File

@ -20,11 +20,27 @@
at runtime from the About dialog for additional information.
-->
<template>
<div :aria-label="`Stacked Plot Item ${childObject.name}`"></div>
<div :aria-label="`Stacked Plot Item ${childObject.name}`">
<Plot
ref="plotComponent"
:hide-legend="hideLegend"
:limit-line-labels="showLimitLineLabels"
:grid-lines="gridLines"
:cursor-guide="cursorGuide"
:parent-y-tick-width="parentYTickWidth"
:options="options"
:color-palette="colorPalette"
:class="isStale && 'is-stale'"
@config-loaded="onConfigLoaded"
@lock-highlight-point="onLockHighlightPointUpdated"
@highlights="onHighlightsUpdated"
@plot-y-tick-width="onYTickWidthChange"
@cursor-guide="onCursorGuideChange"
@grid-lines="onGridLinesChange"
/>
</div>
</template>
<script>
import mount from 'utils/mount';
import configStore from '@/plugins/plot/configuration/ConfigStore';
import PlotConfigurationModel from '@/plugins/plot/configuration/PlotConfigurationModel';
import stalenessMixin from '@/ui/mixins/staleness-mixin';
@ -33,8 +49,17 @@ import Plot from '../PlotView.vue';
import conditionalStylesMixin from './mixins/objectStyles-mixin.js';
export default {
components: {
Plot
},
mixins: [conditionalStylesMixin, stalenessMixin],
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
provide() {
return {
openmct: this.openmct,
domainObject: this.childObject
};
},
props: {
childObject: {
type: Object,
@ -97,37 +122,6 @@ export default {
'grid-lines',
'plot-y-tick-width'
],
data() {
return {
staleObjects: []
};
},
watch: {
gridLines(newGridLines) {
this.updateComponentProp('gridLines', newGridLines);
},
cursorGuide(newCursorGuide) {
this.updateComponentProp('cursorGuide', newCursorGuide);
},
parentYTickWidth(width) {
this.updateComponentProp('parentYTickWidth', width);
},
showLimitLineLabels: {
handler(data) {
this.updateComponentProp('limitLineLabels', data);
},
deep: true
},
hideLegend(newHideLegend) {
this.updateComponentProp('hideLegend', newHideLegend);
},
staleObjects: {
handler() {
this.updateComponentProp('isStale', this.isStale);
},
deep: true
}
},
mounted() {
this.updateView();
this.isEditing = this.openmct.editor.isEditing();
@ -167,39 +161,12 @@ export default {
}
}
},
updateComponentProp(prop, value) {
if (this.component) {
this.component[prop] = value;
}
},
updateView() {
if (this._destroy) {
this._destroy();
this.component = null;
this.$el.innerHTML = '';
}
const onYTickWidthChange = this.onYTickWidthChange;
const onLockHighlightPointUpdated = this.onLockHighlightPointUpdated;
const onHighlightsUpdated = this.onHighlightsUpdated;
const onConfigLoaded = this.onConfigLoaded;
const onCursorGuideChange = this.onCursorGuideChange;
const onGridLinesChange = this.onGridLinesChange;
const openmct = this.openmct;
const path = this.path;
//If this object is not persistable, then package it with it's parent
const object = this.getPlotObject();
const getProps = this.getProps;
const isMissing = openmct.objects.isMissing(object);
if (this.openmct.telemetry.isTelemetryObject(object)) {
this.subscribeToStaleness(object, (stalenessResponse) => {
this.updateComponentProp('isStale', stalenessResponse.isStale);
});
this.subscribeToStaleness(object);
} else {
// possibly overlay or other composition based plot
this.composition = this.openmct.composition.get(object);
@ -209,61 +176,6 @@ export default {
this.composition.load();
}
const { vNode, destroy } = mount(
{
components: {
Plot
},
provide: {
openmct,
domainObject: object,
path,
renderWhenVisible: this.renderWhenVisible
},
data() {
return {
...getProps(),
onYTickWidthChange,
onLockHighlightPointUpdated,
onHighlightsUpdated,
onConfigLoaded,
onCursorGuideChange,
onGridLinesChange,
isMissing,
loading: false
};
},
methods: {
loadingUpdated(loaded) {
this.loading = loaded;
}
},
template: `
<Plot ref="plotComponent" v-if="!isMissing"
:class="{'is-stale': isStale}"
:grid-lines="gridLines"
:hide-legend="hideLegend"
:cursor-guide="cursorGuide"
:parent-limit-line-labels="limitLineLabels"
:options="options"
:parent-y-tick-width="parentYTickWidth"
:color-palette="colorPalette"
@loading-updated="loadingUpdated"
@config-loaded="onConfigLoaded"
@lock-highlight-point="onLockHighlightPointUpdated"
@highlights="onHighlightsUpdated"
@plot-y-tick-width="onYTickWidthChange"
@cursor-guide="onCursorGuideChange"
@grid-lines="onGridLinesChange"/>`
},
{
app: this.openmct.app,
element: this.$el
}
);
this.component = vNode.componentInstance;
this._destroy = destroy;
if (this.isEditing) {
this.setSelection();
}
@ -296,20 +208,8 @@ export default {
this.removeSelectable = this.openmct.selection.selectable(this.$el, this.context);
},
getProps() {
return {
hideLegend: this.hideLegend,
limitLineLabels: this.showLimitLineLabels,
gridLines: this.gridLines,
cursorGuide: this.cursorGuide,
parentYTickWidth: this.parentYTickWidth,
options: this.options,
colorPalette: this.colorPalette,
isStale: this.isStale
};
},
getPlotObject() {
if (this.childObject.configuration && this.childObject.configuration.series) {
if (this.childObject.configuration?.series) {
//If the object has a configuration (like an overlay plot), allow initialization of the config from it's persisted config
return this.childObject;
} else {

View File

@ -490,7 +490,7 @@ describe('the plugin', function () {
max: 10
});
expect(
plotViewComponentObject.$refs.stackedPlotItems[0].component.$refs.plotComponent.$refs.mctPlot.xScale.domain()
plotViewComponentObject.$refs.stackedPlotItems[0].$refs.plotComponent.$refs.mctPlot.xScale.domain()
).toEqual({
min: 0,
max: 10
@ -507,8 +507,7 @@ describe('the plugin', function () {
});
const yAxesScales =
plotViewComponentObject.$refs.stackedPlotItems[0].component.$refs.plotComponent.$refs
.mctPlot.yScale;
plotViewComponentObject.$refs.stackedPlotItems[0].$refs.plotComponent.$refs.mctPlot.yScale;
yAxesScales.forEach((yAxisScale) => {
expect(yAxisScale.scale.domain()).toEqual({
min: 10,
@ -523,7 +522,7 @@ describe('the plugin', function () {
);
let hasStyles = 0;
conditionalStylesContainer.forEach((el) => {
if (el.style.backgroundColor !== '') {
if (el.style.backgroundColor) {
hasStyles++;
}
});