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

View File

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

View File

@ -20,11 +20,27 @@
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<template> <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> </template>
<script> <script>
import mount from 'utils/mount';
import configStore from '@/plugins/plot/configuration/ConfigStore'; import configStore from '@/plugins/plot/configuration/ConfigStore';
import PlotConfigurationModel from '@/plugins/plot/configuration/PlotConfigurationModel'; import PlotConfigurationModel from '@/plugins/plot/configuration/PlotConfigurationModel';
import stalenessMixin from '@/ui/mixins/staleness-mixin'; import stalenessMixin from '@/ui/mixins/staleness-mixin';
@ -33,8 +49,17 @@ import Plot from '../PlotView.vue';
import conditionalStylesMixin from './mixins/objectStyles-mixin.js'; import conditionalStylesMixin from './mixins/objectStyles-mixin.js';
export default { export default {
components: {
Plot
},
mixins: [conditionalStylesMixin, stalenessMixin], mixins: [conditionalStylesMixin, stalenessMixin],
inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'], inject: ['openmct', 'domainObject', 'path', 'renderWhenVisible'],
provide() {
return {
openmct: this.openmct,
domainObject: this.childObject
};
},
props: { props: {
childObject: { childObject: {
type: Object, type: Object,
@ -97,37 +122,6 @@ export default {
'grid-lines', 'grid-lines',
'plot-y-tick-width' '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() { mounted() {
this.updateView(); this.updateView();
this.isEditing = this.openmct.editor.isEditing(); this.isEditing = this.openmct.editor.isEditing();
@ -167,39 +161,12 @@ export default {
} }
} }
}, },
updateComponentProp(prop, value) {
if (this.component) {
this.component[prop] = value;
}
},
updateView() { 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 //If this object is not persistable, then package it with it's parent
const object = this.getPlotObject(); const object = this.getPlotObject();
const getProps = this.getProps;
const isMissing = openmct.objects.isMissing(object);
if (this.openmct.telemetry.isTelemetryObject(object)) { if (this.openmct.telemetry.isTelemetryObject(object)) {
this.subscribeToStaleness(object, (stalenessResponse) => { this.subscribeToStaleness(object);
this.updateComponentProp('isStale', stalenessResponse.isStale);
});
} else { } else {
// possibly overlay or other composition based plot // possibly overlay or other composition based plot
this.composition = this.openmct.composition.get(object); this.composition = this.openmct.composition.get(object);
@ -209,61 +176,6 @@ export default {
this.composition.load(); 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) { if (this.isEditing) {
this.setSelection(); this.setSelection();
} }
@ -296,20 +208,8 @@ export default {
this.removeSelectable = this.openmct.selection.selectable(this.$el, this.context); 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() { 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 //If the object has a configuration (like an overlay plot), allow initialization of the config from it's persisted config
return this.childObject; return this.childObject;
} else { } else {

View File

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