Skip to content

Commit

Permalink
addressing PR comments
Browse files Browse the repository at this point in the history
  • Loading branch information
jvigliotta committed May 3, 2024
1 parent 5d0f689 commit 1f3ddd5
Show file tree
Hide file tree
Showing 10 changed files with 114 additions and 10,531 deletions.
3 changes: 3 additions & 0 deletions src/AMMOSPlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,15 @@ define([

openmct.install(openmct.plugins.DefaultRootName('VISTA'));
openmct.install(new ExportDataAction.default([
'table',
'telemetry.plot.overlay',
'telemetry.plot.stacked',
'vista.channel',
'vista.channelGroup',
'vista.chanTableGroup',
'vista.evr',
'vista.evrModule',
'vista.evrSource',
'vista.evrView'
]));
openmct.install(ActionModifiersPlugin.default());
Expand Down
70 changes: 45 additions & 25 deletions src/exportDataAction/ExportDataAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,64 @@ class ExportDataAction {

appliesTo(objectPath) {
const domainObject = objectPath[0];
const isValidType = this.validTypes.includes(domainObject?.type);
if (!isValidType) {

if (!this.isValidType(domainObject)) {
return false;
}

const hasComposition = this.openmct.composition.get(domainObject) !== undefined;
const hasHistoricalTelemetry = this.openmct.telemetry.isTelemetryObject(domainObject) &&
!domainObject.telemetry.realtimeOnly;
const hasHistoricalTelemetry = this.hasHistoricalTelemetry(domainObject);

return hasHistoricalTelemetry || !hasHistoricalTelemetry && hasComposition;
}

invoke(objectPath) {
const domainObject = objectPath[0];
async invoke([domainObject]) {
const progressDialog = this.openmct.notifications.progress('Exporting CSV', 'unknown');
const runTask = (domainObjects) => new ExportDataTask(this.openmct, domainObject.name, domainObjects).invoke();
const exportData = async (object) => {
if (this.openmct.telemetry.isTelemetryObject(object)) {
runTask([object]);
} else {
const compositionCollection = this.openmct.composition.get(object);
const composition = await compositionCollection.load();
runTask(composition);
}
}

const success = (value) => {
progressDialog.dismiss();
return value;
};

const failure = (error) => {
progressDialog.dismiss();
try {
await this.exportData(domainObject);
} catch (error) {
console.error(error);
this.openmct.notifications.error('Error exporting CSV');
};
} finally {
progressDialog.dismiss();
}
}

async exportData(domainObject) {
if (this.openmct.telemetry.isTelemetryObject(domainObject)) {
await this.runExportTask([domainObject]);
} else {
await this.exportCompositionData(domainObject);
}
}

async exportCompositionData(domainObject) {
const compositionCollection = this.openmct.composition.get(domainObject);
const composition = await compositionCollection.load();
const filteredComposition = composition.filter(obj =>
this.isValidType(obj) && this.hasHistoricalTelemetry(obj)
);

if (filteredComposition.length > 0) {
await this.runExportTask(filteredComposition);
} else {
this.openmct.notifications.info('No historical data to export');
}
}

runExportTask(domainObjects) {
const task = new ExportDataTask(this.openmct, domainObjects[0].name, domainObjects);

return task.invoke();
}

isValidType(domainObject) {
return this.validTypes.includes(domainObject?.type);
}

return exportData(domainObject).then(success, failure);
hasHistoricalTelemetry(domainObject) {
return this.openmct.telemetry.isTelemetryObject(domainObject) && !domainObject.telemetry.realtimeOnly;
}
}

Expand Down
61 changes: 30 additions & 31 deletions src/exportDataAction/ExportDataTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,43 +21,42 @@ export default class ExportDataTask {
* successfully completed, or be rejected if an error occurs
*/
async invoke() {
const headers = [];
const headerSet = {};
const requestTelemetry = async (domainObject) => {
const telemetry = await this.openmct.telemetry.request(domainObject);
const telemetryData = await this.fetchAllTelemetryData();
const headers = this.extractHeaders(telemetryData);
const allTelemetry = telemetryData.flat();

return telemetry;
};
const pullHeaders = (dataArray) => {
dataArray.forEach((data) => {
const datum = data[0] || {};
Object.keys(datum).forEach((key) => {
if (!headerSet[key]) {
headerSet[key] = true;
headers.push(key);
}
});
});

return dataArray;
};
const exportAsCSV = (rows) => this.exportCSV(rows, {
headers,
filename: this.filename
return this.exportAsCSV(allTelemetry, headers);
}

async fetchAllTelemetryData() {
return Promise.all(this.domainObjects.map(async (domainObject) => {
return this.openmct.telemetry.request(domainObject, { strategy: 'comprehensive' });
}));
}

extractHeaders(telemetryData) {
const headerSet = new Set();
telemetryData.forEach(data => {
const datum = data[0] || {};
Object.keys(datum).forEach(key => headerSet.add(key));
});
const telemetry = await Promise.all(this.domainObjects.map(requestTelemetry));
pullHeaders(telemetry);
const allTelemetry = telemetry.flat();
return Array.from(headerSet);
}

return exportAsCSV(allTelemetry);
exportAsCSV(rows, headers) {
const options = {
headers: headers,
filename: this.filename
};
return this.exportCSV(rows, options);
}

exportCSV(rows, options) {
let headers = (options && options.headers)
|| (Object.keys((rows[0] || {})).sort());
let filename = `${(options && options.filename) || 'export'}.csv`;
let csvText = new CSV(rows, { header: headers }).encode();
let blob = new Blob([csvText], { type: "text/csv" });
const headers = options.headers || Object.keys((rows[0] || {})).sort();
const filename = `${options.filename || 'export'}.csv`;
const csvText = new CSV(rows, { header: headers }).encode();
const blob = new Blob([csvText], { type: "text/csv" });
saveAs(blob, filename);
}
}

13 changes: 7 additions & 6 deletions src/metadataAction/metadataAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ export default class MetadataAction {
this.openmct = openmct;
}
invoke(objectPath) {
let domainObject = objectPath[0],
name = domainObject.name,
attributes = domainObject.telemetry.definition,
component = new Vue ({
const domainObject = objectPath[0];
const name = domainObject.name;
const attributes = domainObject.telemetry.definition;
const component = new Vue ({
provide: {
name,
attributes
Expand All @@ -23,8 +23,9 @@ export default class MetadataAction {
MetadataListView
},
template: '<MetadataListView/>'
}),
overlay = this.openmct.overlays.overlay({
});

this.openmct.overlays.overlay({
element: component.$mount().$el,
size: 'large',
dismissable: true,
Expand Down
Binary file removed src/styles/images/bg-splash.jpg
Binary file not shown.
33 changes: 0 additions & 33 deletions src/styles/images/logo-app-shdw.svg

This file was deleted.

Loading

0 comments on commit 1f3ddd5

Please sign in to comment.