mirror of
https://github.com/nasa/openmct.git
synced 2025-02-11 21:26:28 +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
|
// make sure headers are visible initially
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||||
|
|
||||||
// hide timestamp column
|
// hide timestamp column
|
||||||
await page.getByLabel('Timestamp').uncheck();
|
await page.getByLabel('Timestamp').uncheck();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
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('Units').uncheck();
|
||||||
|
await page.getByLabel('Type').uncheck();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).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
|
// save and reload and verify they columns are still hidden
|
||||||
await page.locator('button[title="Save"]').click();
|
await page.locator('button[title="Save"]').click();
|
||||||
@ -70,6 +74,7 @@ test.describe('Testing LAD table configuration', () => {
|
|||||||
await page.reload();
|
await page.reload();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeHidden();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||||
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||||
|
|
||||||
// Edit LAD table
|
// Edit LAD table
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
@ -78,6 +83,7 @@ test.describe('Testing LAD table configuration', () => {
|
|||||||
// show timestamp column
|
// show timestamp column
|
||||||
await page.getByLabel('Timestamp').check();
|
await page.getByLabel('Timestamp').check();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||||
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
|
|
||||||
// save and reload and make sure only timestamp is still visible
|
// 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.locator('text=Save and Finish Editing').click();
|
||||||
await page.reload();
|
await page.reload();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
await expect(page.getByRole('cell', { name: 'Units' })).toBeHidden();
|
||||||
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeHidden();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
|
|
||||||
// Edit LAD table
|
// Edit LAD table
|
||||||
await page.locator('[title="Edit"]').click();
|
await page.locator('[title="Edit"]').click();
|
||||||
await page.getByRole('tab', { name: 'LAD Table Configuration' }).getByText('LAD Table Configuration').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('Units').check();
|
||||||
|
await page.getByLabel('Type').check();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).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('button[title="Save"]').click();
|
||||||
await page.locator('text=Save and Finish Editing').click();
|
await page.locator('text=Save and Finish Editing').click();
|
||||||
await page.reload();
|
await page.reload();
|
||||||
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Timestamp' })).toBeVisible();
|
||||||
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
await expect(page.getByRole('cell', { name: 'Units' })).toBeVisible();
|
||||||
|
await expect(page.getByRole('cell', { name: 'Type' })).toBeVisible();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<tr
|
<tr
|
||||||
class="js-lad-table__body__row"
|
class="js-lad-table__body__row c-table__selectable-row"
|
||||||
|
@click="clickedRow"
|
||||||
@contextmenu.prevent="showContextMenu"
|
@contextmenu.prevent="showContextMenu"
|
||||||
>
|
>
|
||||||
<td class="js-first-data">{{ domainObject.name }}</td>
|
<td class="js-first-data">{{ domainObject.name }}</td>
|
||||||
@ -40,6 +41,10 @@
|
|||||||
>
|
>
|
||||||
{{ unit }}
|
{{ unit }}
|
||||||
</td>
|
</td>
|
||||||
|
<td
|
||||||
|
v-if="showType"
|
||||||
|
class="js-type-data"
|
||||||
|
>{{ typeLabel }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -52,6 +57,9 @@ const CONTEXT_MENU_ACTIONS = [
|
|||||||
];
|
];
|
||||||
const BLANK_VALUE = '---';
|
const BLANK_VALUE = '---';
|
||||||
|
|
||||||
|
import identifierToString from '/src/tools/url';
|
||||||
|
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'currentView'],
|
inject: ['openmct', 'currentView'],
|
||||||
props: {
|
props: {
|
||||||
@ -83,17 +91,28 @@ export default {
|
|||||||
datum: undefined,
|
datum: undefined,
|
||||||
timestamp: undefined,
|
timestamp: undefined,
|
||||||
timestampKey: undefined,
|
timestampKey: undefined,
|
||||||
|
composition: [],
|
||||||
unit: ''
|
unit: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
value() {
|
value() {
|
||||||
if (!this.datum) {
|
if (!this.datum || this.isAggregate) {
|
||||||
return BLANK_VALUE;
|
return BLANK_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.formats[this.valueKey].format(this.datum);
|
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() {
|
valueClasses() {
|
||||||
let classes = [];
|
let classes = [];
|
||||||
|
|
||||||
@ -113,7 +132,7 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
formattedTimestamp() {
|
formattedTimestamp() {
|
||||||
if (!this.timestamp) {
|
if (!this.timestamp || this.isAggregate) {
|
||||||
return BLANK_VALUE;
|
return BLANK_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,12 +150,19 @@ export default {
|
|||||||
},
|
},
|
||||||
showTimestamp() {
|
showTimestamp() {
|
||||||
return !this.configuration?.hiddenColumns?.timestamp;
|
return !this.configuration?.hiddenColumns?.timestamp;
|
||||||
|
},
|
||||||
|
showType() {
|
||||||
|
return !this.configuration?.hiddenColumns?.type;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
async mounted() {
|
||||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
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);
|
this.timeContext = this.openmct.time.getContextForView(this.objectPath);
|
||||||
|
|
||||||
@ -170,11 +196,15 @@ export default {
|
|||||||
if (this.hasUnits) {
|
if (this.hasUnits) {
|
||||||
this.setUnit();
|
this.setUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.previewAction = new PreviewAction(this.openmct);
|
||||||
|
this.previewAction.on('isVisible', this.togglePreviewState);
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.openmct.time.off('timeSystem', this.updateTimeSystem);
|
this.openmct.time.off('timeSystem', this.updateTimeSystem);
|
||||||
this.telemetryCollection.off('add', this.setLatestValues);
|
this.telemetryCollection.off('add', this.setLatestValues);
|
||||||
this.telemetryCollection.off('clear', this.resetValues);
|
this.telemetryCollection.off('clear', this.resetValues);
|
||||||
|
this.previewAction.off('isVisible', this.togglePreviewState);
|
||||||
|
|
||||||
this.telemetryCollection.destroy();
|
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) {
|
setLatestValues(data) {
|
||||||
this.latestDatum = data[data.length - 1];
|
this.latestDatum = data[data.length - 1];
|
||||||
this.updateView();
|
this.updateView();
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
<th v-if="showTimestamp">Timestamp</th>
|
<th v-if="showTimestamp">Timestamp</th>
|
||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
<th v-if="hasUnits">Units</th>
|
<th v-if="hasUnits">Units</th>
|
||||||
|
<th v-if="showType">Type</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@ -93,6 +94,9 @@ export default {
|
|||||||
showTimestamp() {
|
showTimestamp() {
|
||||||
return !this.configuration?.hiddenColumns?.timestamp;
|
return !this.configuration?.hiddenColumns?.timestamp;
|
||||||
},
|
},
|
||||||
|
showType() {
|
||||||
|
return !this.configuration?.hiddenColumns?.type;
|
||||||
|
},
|
||||||
staleClass() {
|
staleClass() {
|
||||||
if (this.staleObjects.length !== 0) {
|
if (this.staleObjects.length !== 0) {
|
||||||
return 'is-stale';
|
return 'is-stale';
|
||||||
|
@ -74,7 +74,8 @@ export default {
|
|||||||
return {
|
return {
|
||||||
headers: {
|
headers: {
|
||||||
timestamp: 'Timestamp',
|
timestamp: 'Timestamp',
|
||||||
units: 'Units'
|
units: 'Units',
|
||||||
|
type: 'Type'
|
||||||
},
|
},
|
||||||
ladTableConfiguration,
|
ladTableConfiguration,
|
||||||
isEditing: this.openmct.editor.isEditing(),
|
isEditing: this.openmct.editor.isEditing(),
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th v-if="showTimestamp">Timestamp</th>
|
<th v-if="showTimestamp">Timestamp</th>
|
||||||
<th>Value</th>
|
<th>Value</th>
|
||||||
|
<th v-if="showType">Type</th>
|
||||||
<th v-if="hasUnits">Units</th>
|
<th v-if="hasUnits">Units</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -112,6 +113,9 @@ export default {
|
|||||||
showTimestamp() {
|
showTimestamp() {
|
||||||
return !this.configuration?.hiddenColumns?.timestamp;
|
return !this.configuration?.hiddenColumns?.timestamp;
|
||||||
},
|
},
|
||||||
|
showType() {
|
||||||
|
return !this.configuration?.hiddenColumns?.type;
|
||||||
|
},
|
||||||
staleClass() {
|
staleClass() {
|
||||||
if (this.staleObjects.length !== 0) {
|
if (this.staleObjects.length !== 0) {
|
||||||
return 'is-stale';
|
return 'is-stale';
|
||||||
|
@ -152,23 +152,42 @@ describe("The LAD Table", () => {
|
|||||||
}
|
}
|
||||||
}).telemetry;
|
}).telemetry;
|
||||||
|
|
||||||
// add another telemetry object as composition in lad table to test multi rows
|
const aggregateTelemetryObj = getMockObjects({
|
||||||
mockObj.ladTable.composition.push(anotherTelemetryObj.identifier);
|
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 () => {
|
beforeEach(async () => {
|
||||||
let telemetryRequestResolve;
|
let telemetryRequestResolve;
|
||||||
let telemetryObjectResolve;
|
let telemetryObjectResolve;
|
||||||
let anotherTelemetryObjectResolve;
|
let anotherTelemetryObjectResolve;
|
||||||
let telemetryRequestPromise = new Promise((resolve) => {
|
let aggregateTelemetryObjectResolve;
|
||||||
|
const telemetryRequestPromise = new Promise((resolve) => {
|
||||||
telemetryRequestResolve = resolve;
|
telemetryRequestResolve = resolve;
|
||||||
});
|
});
|
||||||
let telemetryObjectPromise = new Promise((resolve) => {
|
const telemetryObjectPromise = new Promise((resolve) => {
|
||||||
telemetryObjectResolve = resolve;
|
telemetryObjectResolve = resolve;
|
||||||
});
|
});
|
||||||
let anotherTelemetryObjectPromise = new Promise((resolve) => {
|
const anotherTelemetryObjectPromise = new Promise((resolve) => {
|
||||||
anotherTelemetryObjectResolve = resolve;
|
anotherTelemetryObjectResolve = resolve;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const aggregateTelemetryObjectPromise = new Promise((resolve) => {
|
||||||
|
aggregateTelemetryObjectResolve = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
spyOnBuiltins(['requestAnimationFrame']);
|
spyOnBuiltins(['requestAnimationFrame']);
|
||||||
window.requestAnimationFrame.and.callFake((callBack) => {
|
window.requestAnimationFrame.and.callFake((callBack) => {
|
||||||
callBack();
|
callBack();
|
||||||
@ -185,10 +204,14 @@ describe("The LAD Table", () => {
|
|||||||
telemetryObjectResolve(mockObj.telemetry);
|
telemetryObjectResolve(mockObj.telemetry);
|
||||||
|
|
||||||
return telemetryObjectPromise;
|
return telemetryObjectPromise;
|
||||||
} else {
|
} else if (obj.key === 'another-telemetry-object') {
|
||||||
anotherTelemetryObjectResolve(anotherTelemetryObj);
|
anotherTelemetryObjectResolve(anotherTelemetryObj);
|
||||||
|
|
||||||
return anotherTelemetryObjectPromise;
|
return anotherTelemetryObjectPromise;
|
||||||
|
} else {
|
||||||
|
aggregateTelemetryObjectResolve(aggregateTelemetryObj);
|
||||||
|
|
||||||
|
return aggregateTelemetryObjectPromise;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -202,7 +225,7 @@ describe("The LAD Table", () => {
|
|||||||
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
ladTableView = ladTableViewProvider.view(mockObj.ladTable, [mockObj.ladTable]);
|
||||||
ladTableView.show(child, true);
|
ladTableView.show(child, true);
|
||||||
|
|
||||||
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise]);
|
await Promise.all([telemetryRequestPromise, telemetryObjectPromise, anotherTelemetryObjectPromise, aggregateTelemetryObjectResolve]);
|
||||||
await Vue.nextTick();
|
await Vue.nextTick();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -217,6 +240,16 @@ describe("The LAD Table", () => {
|
|||||||
await Vue.nextTick();
|
await Vue.nextTick();
|
||||||
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
|
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
|
||||||
expect(latestDate).toBe(expectedDate);
|
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", () => {
|
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) {
|
tr:not(.c-table__group-header) + tr:not(.c-table__group-header) {
|
||||||
border-top: 1px solid $colorTabBorder;
|
border-top: 1px solid $colorTabBorder;
|
||||||
}
|
}
|
||||||
|
transition: $transOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__selectable-row {cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background: $colorListItemBgHov;
|
||||||
|
filter: $filterHov;
|
||||||
|
transition: $transIn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__group-header {
|
&__group-header {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user