mirror of
https://github.com/nasa/openmct.git
synced 2025-01-30 16:13:53 +00:00
Differentiate aggregate telenmetry in LAD tables (#6406)
* allow lad tables rows to be selected * rows now clickable and previewable * trying to add type column * aggregate and telemetry * if aggregate, use blank for value and timestamps * remove extraneous path lookup * cleanup css * add tests * allow hiding of type column * adjust tests to include type column
This commit is contained in:
parent
600890c4a6
commit
1f30706d27
@ -53,16 +53,20 @@ test.describe('Testing LAD table configuration', () => {
|
||||
// make sure headers are visible initially
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||
|
||||
// hide timestamp column
|
||||
await page.getByLabel('Timestamp').uncheck();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||
|
||||
// hide units column
|
||||
// hide units & type column
|
||||
await page.getByLabel('Units').uncheck();
|
||||
await page.getByLabel('Type').uncheck();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||
|
||||
// save and reload and verify they columns are still hidden
|
||||
await page.locator('button[title="Save"]').click();
|
||||
@ -70,6 +74,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await page.reload();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
@ -78,6 +83,7 @@ test.describe('Testing LAD table configuration', () => {
|
||||
// show timestamp column
|
||||
await page.getByLabel('Timestamp').check();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||
|
||||
// save and reload and make sure only timestamp is still visible
|
||||
@ -85,23 +91,27 @@ test.describe('Testing LAD table configuration', () => {
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
await page.reload();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||
|
||||
// Edit LAD table
|
||||
await page.locator('[title="Edit"]').click();
|
||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).getByText('LAD Table Configuration').click();
|
||||
|
||||
// show units column
|
||||
// show units and type columns
|
||||
await page.getByLabel('Units').check();
|
||||
await page.getByLabel('Type').check();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||
|
||||
// save and reload and make sure both columns are still visible
|
||||
// save and reload and make sure all columns are still visible
|
||||
await page.locator('button[title="Save"]').click();
|
||||
await page.locator('text=Save and Finish Editing').click();
|
||||
await page.reload();
|
||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -22,7 +22,8 @@
|
||||
|
||||
<template>
|
||||
<tr
|
||||
class="js-lad-table__body__row"
|
||||
class="js-lad-table__body__row c-table__selectable-row"
|
||||
@click="clickedRow"
|
||||
@contextmenu.prevent="showContextMenu"
|
||||
>
|
||||
<td class="js-first-data">{{ domainObject.name }}</td>
|
||||
@ -40,6 +41,10 @@
|
||||
>
|
||||
{{ unit }}
|
||||
</td>
|
||||
<td
|
||||
v-if="showType"
|
||||
class="js-type-data"
|
||||
>{{ typeLabel }}</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
@ -52,6 +57,9 @@ const CONTEXT_MENU_ACTIONS = [
|
||||
];
|
||||
const BLANK_VALUE = '---';
|
||||
|
||||
import identifierToString from '/src/tools/url';
|
||||
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'currentView'],
|
||||
props: {
|
||||
@ -83,17 +91,28 @@ export default {
|
||||
datum: undefined,
|
||||
timestamp: undefined,
|
||||
timestampKey: undefined,
|
||||
composition: [],
|
||||
unit: ''
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
value() {
|
||||
if (!this.datum) {
|
||||
if (!this.datum || this.isAggregate) {
|
||||
return BLANK_VALUE;
|
||||
}
|
||||
|
||||
return this.formats[this.valueKey].format(this.datum);
|
||||
},
|
||||
typeLabel() {
|
||||
if (this.isAggregate) {
|
||||
return 'Aggregate';
|
||||
}
|
||||
|
||||
return "Telemetry";
|
||||
},
|
||||
isAggregate() {
|
||||
return this.composition && this.composition.length > 0;
|
||||
},
|
||||
valueClasses() {
|
||||
let classes = [];
|
||||
|
||||
@ -113,7 +132,7 @@ export default {
|
||||
|
||||
},
|
||||
formattedTimestamp() {
|
||||
if (!this.timestamp) {
|
||||
if (!this.timestamp || this.isAggregate) {
|
||||
return BLANK_VALUE;
|
||||
}
|
||||
|
||||
@ -131,12 +150,19 @@ export default {
|
||||
},
|
||||
showTimestamp() {
|
||||
return !this.configuration?.hiddenColumns?.timestamp;
|
||||
},
|
||||
showType() {
|
||||
return !this.configuration?.hiddenColumns?.type;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
const compositionCollection = this.openmct.composition.get(this.domainObject);
|
||||
if (compositionCollection) {
|
||||
this.composition = await compositionCollection.load();
|
||||
}
|
||||
|
||||
this.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||
|
||||
@ -170,11 +196,15 @@ export default {
|
||||
if (this.hasUnits) {
|
||||
this.setUnit();
|
||||
}
|
||||
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
this.previewAction.on('isVisible', this.togglePreviewState);
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.time.off('timeSystem', this.updateTimeSystem);
|
||||
this.telemetryCollection.off('add', this.setLatestValues);
|
||||
this.telemetryCollection.off('clear', this.resetValues);
|
||||
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||
|
||||
this.telemetryCollection.destroy();
|
||||
},
|
||||
@ -189,6 +219,20 @@ export default {
|
||||
});
|
||||
}
|
||||
},
|
||||
clickedRow(event) {
|
||||
if (this.openmct.editor.isEditing()) {
|
||||
event.preventDefault();
|
||||
this.preview(this.objectPath);
|
||||
} else {
|
||||
const resultUrl = identifierToString(this.openmct, this.objectPath);
|
||||
this.openmct.router.navigate(resultUrl);
|
||||
}
|
||||
},
|
||||
preview(objectPath) {
|
||||
if (this.previewAction.appliesTo(objectPath)) {
|
||||
this.previewAction.invoke(objectPath);
|
||||
}
|
||||
},
|
||||
setLatestValues(data) {
|
||||
this.latestDatum = data[data.length - 1];
|
||||
this.updateView();
|
||||
|
@ -32,6 +32,7 @@
|
||||
<th v-if="showTimestamp">Timestamp</th>
|
||||
<th>Value</th>
|
||||
<th v-if="hasUnits">Units</th>
|
||||
<th v-if="showType">Type</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@ -93,6 +94,9 @@ export default {
|
||||
showTimestamp() {
|
||||
return !this.configuration?.hiddenColumns?.timestamp;
|
||||
},
|
||||
showType() {
|
||||
return !this.configuration?.hiddenColumns?.type;
|
||||
},
|
||||
staleClass() {
|
||||
if (this.staleObjects.length !== 0) {
|
||||
return 'is-stale';
|
||||
|
@ -74,7 +74,8 @@ export default {
|
||||
return {
|
||||
headers: {
|
||||
timestamp: 'Timestamp',
|
||||
units: 'Units'
|
||||
units: 'Units',
|
||||
type: 'Type'
|
||||
},
|
||||
ladTableConfiguration,
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
|
@ -31,6 +31,7 @@
|
||||
<th>Name</th>
|
||||
<th v-if="showTimestamp">Timestamp</th>
|
||||
<th>Value</th>
|
||||
<th v-if="showType">Type</th>
|
||||
<th v-if="hasUnits">Units</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@ -112,6 +113,9 @@ export default {
|
||||
showTimestamp() {
|
||||
return !this.configuration?.hiddenColumns?.timestamp;
|
||||
},
|
||||
showType() {
|
||||
return !this.configuration?.hiddenColumns?.type;
|
||||
},
|
||||
staleClass() {
|
||||
if (this.staleObjects.length !== 0) {
|
||||
return 'is-stale';
|
||||
|
@ -152,23 +152,42 @@ describe("The LAD Table", () => {
|
||||
}
|
||||
}).telemetry;
|
||||
|
||||
// add another telemetry object as composition in lad table to test multi rows
|
||||
mockObj.ladTable.composition.push(anotherTelemetryObj.identifier);
|
||||
const aggregateTelemetryObj = getMockObjects({
|
||||
objectKeyStrings: ['telemetry'],
|
||||
overwrite: {
|
||||
telemetry: {
|
||||
name: "Aggregate Telemetry Object",
|
||||
identifier: {
|
||||
namespace: "",
|
||||
key: "aggregate-telemetry-object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}).telemetry;
|
||||
|
||||
// add another aggregate telemetry object as composition in lad table to test multi rows
|
||||
aggregateTelemetryObj.composition = [anotherTelemetryObj.identifier];
|
||||
mockObj.ladTable.composition.push(aggregateTelemetryObj.identifier);
|
||||
|
||||
beforeEach(async () => {
|
||||
let telemetryRequestResolve;
|
||||
let telemetryObjectResolve;
|
||||
let anotherTelemetryObjectResolve;
|
||||
let telemetryRequestPromise = new Promise((resolve) => {
|
||||
let aggregateTelemetryObjectResolve;
|
||||
const telemetryRequestPromise = new Promise((resolve) => {
|
||||
telemetryRequestResolve = resolve;
|
||||
});
|
||||
let telemetryObjectPromise = new Promise((resolve) => {
|
||||
const telemetryObjectPromise = new Promise((resolve) => {
|
||||
telemetryObjectResolve = resolve;
|
||||
});
|
||||
let anotherTelemetryObjectPromise = new Promise((resolve) => {
|
||||
const anotherTelemetryObjectPromise = new Promise((resolve) => {
|
||||
anotherTelemetryObjectResolve = resolve;
|
||||
});
|
||||
|
||||
const aggregateTelemetryObjectPromise = new Promise((resolve) => {
|
||||
aggregateTelemetryObjectResolve = resolve;
|
||||
});
|
||||
|
||||
spyOnBuiltins(['requestAnimationFrame']);
|
||||
window.requestAnimationFrame.and.callFake((callBack) => {
|
||||
callBack();
|
||||
@ -185,10 +204,14 @@ describe("The LAD Table", () => {
|
||||
telemetryObjectResolve(mockObj.telemetry);
|
||||
|
||||
return telemetryObjectPromise;
|
||||
} else {
|
||||
} else if (obj.key === 'another-telemetry-object') {
|
||||
anotherTelemetryObjectResolve(anotherTelemetryObj);
|
||||
|
||||
return anotherTelemetryObjectPromise;
|
||||
} else {
|
||||
aggregateTelemetryObjectResolve(aggregateTelemetryObj);
|
||||
|
||||
return aggregateTelemetryObjectPromise;
|
||||
}
|
||||
});
|
||||
|
||||
@ -202,7 +225,7 @@ describe("The LAD Table", () => {
|
||||
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
||||
ladTableView.show(child, true);
|
||||
|
||||
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise]);
|
||||
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise, aggregateTelemetryObjectResolve]);
|
||||
await Vue.nextTick();
|
||||
});
|
||||
|
||||
@ -217,6 +240,16 @@ describe("The LAD Table", () => {
|
||||
await Vue.nextTick();
|
||||
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
|
||||
expect(latestDate).toBe(expectedDate);
|
||||
const dataType = parent.querySelector(TABLE_BODY_ROWS).querySelector('.js-type-data').innerText;
|
||||
expect(dataType).toBe('Telemetry');
|
||||
});
|
||||
|
||||
it("should show aggregate telemetry type with blank data", async () => {
|
||||
await Vue.nextTick();
|
||||
const lastestData = parent.querySelectorAll(TABLE_BODY_ROWS)[1].querySelectorAll('td')[2].innerText;
|
||||
expect(lastestData).toBe('---');
|
||||
const dataType = parent.querySelectorAll(TABLE_BODY_ROWS)[1].querySelector('.js-type-data').innerText;
|
||||
expect(dataType).toBe('Aggregate');
|
||||
});
|
||||
|
||||
it("should show the name provided for the the telemetry producing object", () => {
|
||||
|
@ -150,6 +150,15 @@ div.c-table {
|
||||
tr:not(.c-table__group-header) + tr:not(.c-table__group-header) {
|
||||
border-top: 1px solid $colorTabBorder;
|
||||
}
|
||||
transition: $transOut;
|
||||
}
|
||||
|
||||
&__selectable-row {cursor: pointer;
|
||||
&:hover {
|
||||
background: $colorListItemBgHov;
|
||||
filter: $filterHov;
|
||||
transition: $transIn;
|
||||
}
|
||||
}
|
||||
|
||||
&__group-header {
|
||||
|
Loading…
x
Reference in New Issue
Block a user