mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 02:29:24 +00:00
Compare commits
9 Commits
omm-large-
...
release/2.
Author | SHA1 | Date | |
---|---|---|---|
3c60b0416f | |||
4d93907d58 | |||
6f656a6783 | |||
767fb6c5fd | |||
b0a0b4bb58 | |||
340f4a9e79 | |||
3007b28b0f | |||
20789601b4 | |||
a56cfed732 |
@ -175,11 +175,11 @@ workflows:
|
||||
overall-circleci-commit-status: #These jobs run on every commit
|
||||
jobs:
|
||||
- lint:
|
||||
name: node14-lint
|
||||
node-version: lts/fermium
|
||||
name: node16-lint
|
||||
node-version: lts/gallium
|
||||
- unit-test:
|
||||
name: node18-chrome
|
||||
node-version: "18"
|
||||
node-version: lts/hydrogen
|
||||
- e2e-test:
|
||||
name: e2e-stable
|
||||
node-version: lts/gallium
|
||||
@ -191,15 +191,12 @@ workflows:
|
||||
|
||||
the-nightly: #These jobs do not run on PRs, but against master at night
|
||||
jobs:
|
||||
- unit-test:
|
||||
name: node14-chrome-nightly
|
||||
node-version: lts/fermium
|
||||
- unit-test:
|
||||
name: node16-chrome-nightly
|
||||
node-version: lts/gallium
|
||||
- unit-test:
|
||||
name: node18-chrome
|
||||
node-version: "18"
|
||||
node-version: lts/hydrogen
|
||||
- npm-audit:
|
||||
node-version: lts/gallium
|
||||
- e2e-test:
|
||||
|
1
.github/workflows/pr-platform.yml
vendored
1
.github/workflows/pr-platform.yml
vendored
@ -16,7 +16,6 @@ jobs:
|
||||
- macos-latest
|
||||
- windows-latest
|
||||
node_version:
|
||||
- 14
|
||||
- 16
|
||||
- 18
|
||||
architecture:
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
const { test, expect } = require('../../../../pluginFixtures');
|
||||
const utils = require('../../../../helper/faultUtils');
|
||||
const { selectInspectorTab } = require('../../../../appActions');
|
||||
|
||||
test.describe('The Fault Management Plugin using example faults', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
@ -38,6 +39,7 @@ test.describe('The Fault Management Plugin using example faults', () => {
|
||||
test('When selecting a fault, it has an "is-selected" class and it\'s information shows in the inspector @unstable', async ({ page }) => {
|
||||
await utils.selectFaultItem(page, 1);
|
||||
|
||||
await selectInspectorTab(page, 'Fault Management Configuration');
|
||||
const selectedFaultName = await page.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname').textContent();
|
||||
const inspectorFaultNameCount = await page.locator(`.c-inspector__properties >> :text("${selectedFaultName}")`).count();
|
||||
|
||||
@ -52,6 +54,7 @@ test.describe('The Fault Management Plugin using example faults', () => {
|
||||
const selectedRows = page.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname');
|
||||
expect.soft(await selectedRows.count()).toEqual(2);
|
||||
|
||||
await selectInspectorTab(page, 'Fault Management Configuration');
|
||||
const firstSelectedFaultName = await selectedRows.nth(0).textContent();
|
||||
const secondSelectedFaultName = await selectedRows.nth(1).textContent();
|
||||
const firstNameInInspectorCount = await page.locator(`.c-inspector__properties >> :text("${firstSelectedFaultName}")`).count();
|
||||
|
@ -377,4 +377,31 @@ test.describe('Notebook entry tests', () => {
|
||||
expect.soft(await sanitizedLink.count()).toBe(1);
|
||||
expect(await unsanitizedLink.count()).toBe(0);
|
||||
});
|
||||
test('can export notebook as text', async ({ page }) => {
|
||||
await nbUtils.enterTextEntry(page, `Foo bar entry`);
|
||||
// Click on 3 Dot Menu
|
||||
await page.locator('button[title="More options"]').click();
|
||||
const downloadPromise = page.waitForEvent('download');
|
||||
|
||||
await page.getByRole('menuitem', { name: /Export Notebook as Text/ }).click();
|
||||
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
const download = await downloadPromise;
|
||||
const readStream = await download.createReadStream();
|
||||
const exportedText = await streamToString(readStream);
|
||||
expect(exportedText).toContain('Foo bar entry');
|
||||
});
|
||||
test.fixme('can export multiple notebook entries as text ', async ({ page }) => {});
|
||||
test.fixme('can export all notebook entry metdata', async ({ page }) => {});
|
||||
test.fixme('can export all notebook tags', async ({ page }) => {});
|
||||
test.fixme('can export all notebook snapshots', async ({ page }) => {});
|
||||
|
||||
async function streamToString(readable) {
|
||||
let result = '';
|
||||
for await (const chunk of readable) {
|
||||
result += chunk;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
||||
|
@ -33,6 +33,8 @@ export default function (staticFaults = false) {
|
||||
return Promise.resolve(faultsData);
|
||||
},
|
||||
subscribe(domainObject, callback) {
|
||||
callback({ type: 'global-alarm-status' });
|
||||
|
||||
return () => {};
|
||||
},
|
||||
supportsRequest(domainObject) {
|
||||
|
14
package.json
14
package.json
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "openmct",
|
||||
"version": "2.2.1-SNAPSHOT",
|
||||
"version": "2.2.1",
|
||||
"description": "The Open MCT core platform",
|
||||
"devDependencies": {
|
||||
"@babel/eslint-parser": "7.18.9",
|
||||
"@braintree/sanitize-url": "6.0.2",
|
||||
"@percy/cli": "1.17.0",
|
||||
"@percy/cli": "1.21.0",
|
||||
"@percy/playwright": "1.0.4",
|
||||
"@playwright/test": "1.29.0",
|
||||
"@types/eventemitter3": "1.2.0",
|
||||
@ -20,8 +20,8 @@
|
||||
"d3-axis": "3.0.0",
|
||||
"d3-scale": "3.3.0",
|
||||
"d3-selection": "3.0.0",
|
||||
"eslint": "8.36.0",
|
||||
"eslint-plugin-compat": "4.1.1",
|
||||
"eslint": "8.37.0",
|
||||
"eslint-plugin-compat": "4.1.2",
|
||||
"eslint-plugin-playwright": "0.12.0",
|
||||
"eslint-plugin-vue": "9.10.0",
|
||||
"eslint-plugin-you-dont-need-lodash-underscore": "6.12.0",
|
||||
@ -41,7 +41,7 @@
|
||||
"karma-sourcemap-loader": "0.3.8",
|
||||
"karma-spec-reporter": "0.0.36",
|
||||
"karma-webpack": "5.0.0",
|
||||
"kdbush": "^3.0.0",
|
||||
"kdbush": "3.0.0",
|
||||
"location-bar": "3.0.1",
|
||||
"lodash": "4.17.21",
|
||||
"mini-css-extract-plugin": "2.7.5",
|
||||
@ -59,7 +59,7 @@
|
||||
"sass": "1.59.3",
|
||||
"sass-loader": "13.2.1",
|
||||
"sinon": "15.0.1",
|
||||
"style-loader": "^3.3.1",
|
||||
"style-loader": "3.3.2",
|
||||
"typescript": "4.9.5",
|
||||
"uuid": "9.0.0",
|
||||
"vue": "2.6.14",
|
||||
@ -107,7 +107,7 @@
|
||||
"url": "https://github.com/nasa/openmct.git"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.19.1"
|
||||
"node": ">=16.20.0"
|
||||
},
|
||||
"browserslist": [
|
||||
"Firefox ESR",
|
||||
|
@ -21,18 +21,31 @@
|
||||
*****************************************************************************/
|
||||
|
||||
export default class FaultManagementAPI {
|
||||
/**
|
||||
* @param {import("openmct").OpenMCT} openmct
|
||||
*/
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} provider
|
||||
*/
|
||||
addProvider(provider) {
|
||||
this.provider = provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
supportsActions() {
|
||||
return this.provider?.acknowledgeFault !== undefined && this.provider?.shelveFault !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("../objects/ObjectAPI").DomainObject} domainObject
|
||||
* @returns {Promise.<FaultAPIResponse[]>}
|
||||
*/
|
||||
request(domainObject) {
|
||||
if (!this.provider?.supportsRequest(domainObject)) {
|
||||
return Promise.reject();
|
||||
@ -41,6 +54,11 @@ export default class FaultManagementAPI {
|
||||
return this.provider.request(domainObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import("../objects/ObjectAPI").DomainObject} domainObject
|
||||
* @param {Function} callback
|
||||
* @returns {Function} unsubscribe
|
||||
*/
|
||||
subscribe(domainObject, callback) {
|
||||
if (!this.provider?.supportsSubscribe(domainObject)) {
|
||||
return Promise.reject();
|
||||
@ -49,58 +67,55 @@ export default class FaultManagementAPI {
|
||||
return this.provider.subscribe(domainObject, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Fault} fault
|
||||
* @param {*} ackData
|
||||
*/
|
||||
acknowledgeFault(fault, ackData) {
|
||||
return this.provider.acknowledgeFault(fault, ackData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Fault} fault
|
||||
* @param {*} shelveData
|
||||
* @returns {Promise.<T>}
|
||||
*/
|
||||
shelveFault(fault, shelveData) {
|
||||
return this.provider.shelveFault(fault, shelveData);
|
||||
}
|
||||
}
|
||||
|
||||
/** @typedef {object} Fault
|
||||
* @property {string} type
|
||||
* @property {object} fault
|
||||
* @property {boolean} fault.acknowledged
|
||||
* @property {object} fault.currentValueInfo
|
||||
* @property {number} fault.currentValueInfo.value
|
||||
* @property {string} fault.currentValueInfo.rangeCondition
|
||||
* @property {string} fault.currentValueInfo.monitoringResult
|
||||
* @property {string} fault.id
|
||||
* @property {string} fault.name
|
||||
* @property {string} fault.namespace
|
||||
* @property {number} fault.seqNum
|
||||
* @property {string} fault.severity
|
||||
* @property {boolean} fault.shelved
|
||||
* @property {string} fault.shortDescription
|
||||
* @property {string} fault.triggerTime
|
||||
* @property {object} fault.triggerValueInfo
|
||||
* @property {number} fault.triggerValueInfo.value
|
||||
* @property {string} fault.triggerValueInfo.rangeCondition
|
||||
* @property {string} fault.triggerValueInfo.monitoringResult
|
||||
* @example
|
||||
* {
|
||||
* "type": "",
|
||||
* "fault": {
|
||||
* "acknowledged": true,
|
||||
* "currentValueInfo": {
|
||||
* "value": 0,
|
||||
* "rangeCondition": "",
|
||||
* "monitoringResult": ""
|
||||
* },
|
||||
* "id": "",
|
||||
* "name": "",
|
||||
* "namespace": "",
|
||||
* "seqNum": 0,
|
||||
* "severity": "",
|
||||
* "shelved": true,
|
||||
* "shortDescription": "",
|
||||
* "triggerTime": "",
|
||||
* "triggerValueInfo": {
|
||||
* "value": 0,
|
||||
* "rangeCondition": "",
|
||||
* "monitoringResult": ""
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
/**
|
||||
* @typedef {object} TriggerValueInfo
|
||||
* @property {number} value
|
||||
* @property {string} rangeCondition
|
||||
* @property {string} monitoringResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} CurrentValueInfo
|
||||
* @property {number} value
|
||||
* @property {string} rangeCondition
|
||||
* @property {string} monitoringResult
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} Fault
|
||||
* @property {boolean} acknowledged
|
||||
* @property {CurrentValueInfo} currentValueInfo
|
||||
* @property {string} id
|
||||
* @property {string} name
|
||||
* @property {string} namespace
|
||||
* @property {number} seqNum
|
||||
* @property {string} severity
|
||||
* @property {boolean} shelved
|
||||
* @property {string} shortDescription
|
||||
* @property {string} triggerTime
|
||||
* @property {TriggerValueInfo} triggerValueInfo
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {object} FaultAPIResponse
|
||||
* @property {string} type
|
||||
* @property {Fault} fault
|
||||
*/
|
||||
|
@ -42,8 +42,6 @@ export default {
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.updateFaultList();
|
||||
|
||||
this.unsubscribe = this.openmct.faults
|
||||
.subscribe(this.domainObject, this.updateFault);
|
||||
},
|
||||
@ -68,7 +66,11 @@ export default {
|
||||
this.openmct.faults
|
||||
.request(this.domainObject)
|
||||
.then(faultsData => {
|
||||
this.faultsList = faultsData.map(fd => fd.fault);
|
||||
if (faultsData?.length > 0) {
|
||||
this.faultsList = faultsData.map(fd => fd.fault);
|
||||
} else {
|
||||
this.faultsList = [];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
155
src/plugins/notebook/actions/ExportNotebookAsTextAction.js
Normal file
155
src/plugins/notebook/actions/ExportNotebookAsTextAction.js
Normal file
@ -0,0 +1,155 @@
|
||||
import {saveAs} from 'saveAs';
|
||||
import Moment from 'moment';
|
||||
|
||||
const UNKNOWN_USER = 'Unknown';
|
||||
const UNKNOWN_TIME = 'Unknown';
|
||||
|
||||
export default class ExportNotebookAsTextAction {
|
||||
|
||||
constructor(openmct) {
|
||||
this.openmct = openmct;
|
||||
|
||||
this.cssClass = 'icon-export';
|
||||
this.description = 'Exports notebook contents as a text file';
|
||||
this.group = "action";
|
||||
this.key = 'exportNotebookAsText';
|
||||
this.name = 'Export Notebook as Text';
|
||||
this.priority = 1;
|
||||
}
|
||||
|
||||
invoke(objectPath) {
|
||||
this.showForm(objectPath);
|
||||
}
|
||||
|
||||
getTagName(tagId, availableTags) {
|
||||
const foundTag = availableTags.find(tag => tag.id === tagId);
|
||||
if (foundTag) {
|
||||
return foundTag.label;
|
||||
} else {
|
||||
return tagId;
|
||||
}
|
||||
}
|
||||
|
||||
getTagsForEntry(entry, domainObjectKeyString, annotations) {
|
||||
const foundTags = [];
|
||||
annotations.forEach(annotation => {
|
||||
const target = annotation.targets?.[domainObjectKeyString];
|
||||
if (target?.entryId === entry.id) {
|
||||
annotation.tags.forEach(tag => {
|
||||
if (!foundTags.includes(tag)) {
|
||||
foundTags.push(tag);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return foundTags;
|
||||
}
|
||||
|
||||
formatTimeStamp(timestamp) {
|
||||
if (timestamp) {
|
||||
return `${Moment.utc(timestamp).format('YYYY-MM-DD HH:mm:ss')} UTC`;
|
||||
} else {
|
||||
return UNKNOWN_TIME;
|
||||
}
|
||||
}
|
||||
|
||||
appliesTo(objectPath) {
|
||||
const domainObject = objectPath[0];
|
||||
const type = this.openmct.types.get(domainObject.type);
|
||||
|
||||
return type?.definition?.name === 'Notebook';
|
||||
}
|
||||
|
||||
async onSave(changes, objectPath) {
|
||||
const availableTags = this.openmct.annotation.getAvailableTags();
|
||||
const identifier = objectPath[0].identifier;
|
||||
const domainObject = await this.openmct.objects.get(identifier);
|
||||
let foundAnnotations = [];
|
||||
// only load annotations if there are tags
|
||||
if (availableTags.length) {
|
||||
foundAnnotations = await this.openmct.annotation.getAnnotations(domainObject.identifier);
|
||||
}
|
||||
|
||||
let notebookAsText = `# ${domainObject.name}\n\n`;
|
||||
|
||||
if (changes.exportMetaData) {
|
||||
const createdTimestamp = domainObject.created;
|
||||
const createdBy = domainObject.createdBy ?? UNKNOWN_USER;
|
||||
const modifiedBy = domainObject.modifiedBy ?? UNKNOWN_USER;
|
||||
const modifiedTimestamp = domainObject.modified ?? domainObject.created;
|
||||
notebookAsText += `Created on ${this.formatTimeStamp(createdTimestamp)} by user ${createdBy}\n\n`;
|
||||
notebookAsText += `Updated on ${this.formatTimeStamp(modifiedTimestamp)} by user ${modifiedBy}\n\n`;
|
||||
}
|
||||
|
||||
const notebookSections = domainObject.configuration.sections;
|
||||
const notebookEntries = domainObject.configuration.entries;
|
||||
|
||||
notebookSections.forEach(section => {
|
||||
notebookAsText += `## ${section.name}\n\n`;
|
||||
|
||||
const notebookPages = section.pages;
|
||||
|
||||
notebookPages.forEach(page => {
|
||||
notebookAsText += `### ${page.name}\n\n`;
|
||||
|
||||
const notebookPageEntries = notebookEntries[section.id]?.[page.id];
|
||||
notebookPageEntries.forEach(entry => {
|
||||
if (changes.exportMetaData) {
|
||||
const createdTimestamp = entry.createdOn;
|
||||
const createdBy = entry.createdBy ?? UNKNOWN_USER;
|
||||
const modifiedBy = entry.modifiedBy ?? UNKNOWN_USER;
|
||||
const modifiedTimestamp = entry.modified ?? entry.created;
|
||||
notebookAsText += `Created on ${this.formatTimeStamp(createdTimestamp)} by user ${createdBy}\n\n`;
|
||||
notebookAsText += `Updated on ${this.formatTimeStamp(modifiedTimestamp)} by user ${modifiedBy}\n\n`;
|
||||
}
|
||||
|
||||
if (changes.exportTags) {
|
||||
const domainObjectKeyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
const tags = this.getTagsForEntry(entry, domainObjectKeyString, foundAnnotations);
|
||||
const tagNames = tags.map(tag => this.getTagName(tag, availableTags));
|
||||
if (tagNames) {
|
||||
notebookAsText += `Tags: ${tagNames.join(', ')}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
notebookAsText += `${entry.text}\n\n`;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const blob = new Blob([notebookAsText], {type: "text/markdown"});
|
||||
const fileName = domainObject.name + '.md';
|
||||
saveAs(blob, fileName);
|
||||
}
|
||||
|
||||
async showForm(objectPath) {
|
||||
const formStructure = {
|
||||
title: "Export Notebook Text",
|
||||
sections: [
|
||||
{
|
||||
rows: [
|
||||
{
|
||||
key: "exportMetaData",
|
||||
control: "toggleSwitch",
|
||||
name: "Include Metadata (created/modified, etc.)",
|
||||
required: true,
|
||||
value: false
|
||||
},
|
||||
{
|
||||
name: "Include Tags",
|
||||
control: "toggleSwitch",
|
||||
required: true,
|
||||
key: 'exportTags',
|
||||
value: false
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
const changes = await this.openmct.forms.showForm(formStructure);
|
||||
|
||||
return this.onSave(changes, objectPath);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
import CopyToNotebookAction from './actions/CopyToNotebookAction';
|
||||
import ExportNotebookAsTextAction from './actions/ExportNotebookAsTextAction';
|
||||
import NotebookSnapshotIndicator from './components/NotebookSnapshotIndicator.vue';
|
||||
import NotebookViewProvider from './NotebookViewProvider';
|
||||
import NotebookType from './NotebookType';
|
||||
@ -80,6 +81,7 @@ function installBaseNotebookFunctionality(openmct) {
|
||||
};
|
||||
openmct.types.addType('notebookSnapshotImage', notebookSnapshotImageType);
|
||||
openmct.actions.register(new CopyToNotebookAction(openmct));
|
||||
openmct.actions.register(new ExportNotebookAsTextAction(openmct));
|
||||
|
||||
const notebookSnapshotIndicator = new Vue ({
|
||||
components: {
|
||||
|
@ -46,6 +46,7 @@ export default class RemoteClock extends DefaultClock {
|
||||
|
||||
this.timeTelemetryObject = undefined;
|
||||
this.parseTime = undefined;
|
||||
this.formatTime = undefined;
|
||||
this.metadata = undefined;
|
||||
|
||||
this.lastTick = 0;
|
||||
@ -137,6 +138,10 @@ export default class RemoteClock extends DefaultClock {
|
||||
this.parseTime = (datum) => {
|
||||
return timeFormatter.parse(datum);
|
||||
};
|
||||
|
||||
this.formatTime = (datum) => {
|
||||
return timeFormatter.format(datum);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,7 +88,7 @@ define([], function () {
|
||||
}
|
||||
|
||||
getContextMenuActions() {
|
||||
return ['viewDatumAction'];
|
||||
return ['viewDatumAction', 'viewHistoricalData'];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,14 +175,22 @@ export default {
|
||||
getDatum() {
|
||||
return this.row.fullDatum;
|
||||
},
|
||||
showContextMenu: function (event) {
|
||||
showContextMenu: async function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.updateViewContext();
|
||||
this.markRow(event);
|
||||
|
||||
const contextualDomainObject = await this.row.getContextualDomainObject?.(this.openmct, this.row.objectKeyString);
|
||||
|
||||
let objectPath = this.objectPath;
|
||||
if (contextualDomainObject) {
|
||||
objectPath = objectPath.slice();
|
||||
objectPath.unshift(contextualDomainObject);
|
||||
}
|
||||
|
||||
const actions = this.row.getContextMenuActions().map(key => this.openmct.actions.getAction(key));
|
||||
const menuItems = this.openmct.menus.actionsToMenuItems(actions, this.objectPath, this.currentView);
|
||||
const menuItems = this.openmct.menus.actionsToMenuItems(actions, objectPath, this.currentView);
|
||||
if (menuItems.length) {
|
||||
this.openmct.menus.showMenu(event.x, event.y, menuItems);
|
||||
}
|
||||
|
@ -38,9 +38,8 @@
|
||||
import {getValidatedData} from "../plan/util";
|
||||
import ListView from '../../ui/components/List/ListView.vue';
|
||||
import {getPreciseDuration} from "../../utils/duration";
|
||||
import ticker from 'utils/clock/Ticker';
|
||||
import {SORT_ORDER_OPTIONS} from "./constants";
|
||||
|
||||
import _ from 'lodash';
|
||||
import moment from "moment";
|
||||
import { v4 as uuid } from 'uuid';
|
||||
|
||||
@ -53,16 +52,26 @@ const headerItems = [
|
||||
isSortable: true,
|
||||
property: 'start',
|
||||
name: 'Start Time',
|
||||
format: function (value, object) {
|
||||
return `${moment(value).format(TIME_FORMAT)}Z`;
|
||||
format: function (value, object, key, openmct) {
|
||||
const clock = openmct.time.clock();
|
||||
if (clock && clock.formatTime) {
|
||||
return clock.formatTime(value);
|
||||
} else {
|
||||
return `${moment(value).format(TIME_FORMAT)}Z`;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
defaultDirection: true,
|
||||
isSortable: true,
|
||||
property: 'end',
|
||||
name: 'End Time',
|
||||
format: function (value, object) {
|
||||
return `${moment(value).format(TIME_FORMAT)}Z`;
|
||||
format: function (value, object, key, openmct) {
|
||||
const clock = openmct.time.clock();
|
||||
if (clock && clock.formatTime) {
|
||||
return clock.formatTime(value);
|
||||
} else {
|
||||
return `${moment(value).format(TIME_FORMAT)}Z`;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
defaultDirection: false,
|
||||
@ -119,7 +128,8 @@ export default {
|
||||
this.unlistenConfig = this.openmct.objects.observe(this.domainObject, 'configuration', this.setViewFromConfig);
|
||||
this.removeStatusListener = this.openmct.status.observe(this.domainObject.identifier, this.setStatus);
|
||||
this.status = this.openmct.status.get(this.domainObject.identifier);
|
||||
this.unlistenTicker = ticker.listen(this.clearPreviousActivities);
|
||||
|
||||
this.updateTimestamp = _.throttle(this.updateTimestamp, 1000);
|
||||
this.openmct.time.on('bounds', this.updateTimestamp);
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
|
||||
@ -144,10 +154,6 @@ export default {
|
||||
this.unlistenConfig();
|
||||
}
|
||||
|
||||
if (this.unlistenTicker) {
|
||||
this.unlistenTicker();
|
||||
}
|
||||
|
||||
if (this.removeStatusListener) {
|
||||
this.removeStatusListener();
|
||||
}
|
||||
@ -192,8 +198,8 @@ export default {
|
||||
}
|
||||
},
|
||||
updateTimestamp(_bounds, isTick) {
|
||||
if (isTick === true) {
|
||||
this.timestamp = this.openmct.time.clock().currentValue();
|
||||
if (isTick === true && this.openmct.time.clock() !== undefined) {
|
||||
this.updateTimeStampAndListActivities(this.openmct.time.clock().currentValue());
|
||||
}
|
||||
},
|
||||
setViewFromClock(newClock) {
|
||||
@ -202,12 +208,11 @@ export default {
|
||||
if (isFixedTime) {
|
||||
this.hideAll = false;
|
||||
this.showAll = true;
|
||||
// clear invokes listActivities
|
||||
this.clearPreviousActivities(this.openmct.time.bounds()?.start);
|
||||
this.updateTimeStampAndListActivities(this.openmct.time.bounds()?.start);
|
||||
} else {
|
||||
this.setSort();
|
||||
this.setViewBounds();
|
||||
this.listActivities();
|
||||
this.updateTimeStampAndListActivities(this.openmct.time.clock().currentValue());
|
||||
}
|
||||
},
|
||||
addItem(domainObject) {
|
||||
@ -346,12 +351,8 @@ export default {
|
||||
// sort by start time
|
||||
this.planActivities = activities.sort(this.sortByStartTime);
|
||||
},
|
||||
clearPreviousActivities(time) {
|
||||
if (time instanceof Date) {
|
||||
this.timestamp = time.getTime();
|
||||
} else {
|
||||
this.timestamp = time;
|
||||
}
|
||||
updateTimeStampAndListActivities(time) {
|
||||
this.timestamp = time;
|
||||
|
||||
this.listActivities();
|
||||
},
|
||||
|
@ -37,7 +37,7 @@ export default {
|
||||
// eslint-disable-next-line you-dont-need-lodash-underscore/get
|
||||
let value = _.get(this.item, property.key);
|
||||
if (property.format) {
|
||||
value = property.format(value, this.item, property.key);
|
||||
value = property.format(value, this.item, property.key, this.openmct);
|
||||
}
|
||||
|
||||
values.push({
|
||||
|
Reference in New Issue
Block a user