mirror of
https://github.com/nasa/openmct.git
synced 2025-06-19 07:38:15 +00:00
Remove legacy formats (#4531)
* Remove legacy bundles * Replace legacy format management with vanilla JS * Redefine legacy formats in plugins instead of bundles * Remove 'draft' from API documentation * Remove focus from test spec * Register local time system using new API * Fixed broken custom formatter test spec * Make capitalization consistent * Rewrite test for terse formatting for time conductor * Make dependency on UTCTimeFormat explicit Co-authored-by: John Hill <john.c.hill@nasa.gov>
This commit is contained in:
@ -1,29 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import UTCTimeFormat from './UTCTimeFormat';
|
||||
|
||||
export default function () {
|
||||
return function install(openmct) {
|
||||
openmct.telemetry.addFormat(new UTCTimeFormat());
|
||||
};
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2021, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import UTCTimeFormat from './UTCTimeFormat.js';
|
||||
|
||||
describe('the plugin', () => {
|
||||
const UTC_KEY = 'utc';
|
||||
const JUNK = 'junk';
|
||||
const MOON_LANDING_TIMESTAMP = -14256000000;
|
||||
const MOON_LANDING_DEFAULT_FORMAT = '1969-07-20 00:00:00.000Z';
|
||||
const MOON_LANDING_FORMATTED_DATES = [
|
||||
'1969-07-20 00:00:00.000',
|
||||
'1969-07-20 00:00:00.000+00:00',
|
||||
'1969-07-20 00:00:00',
|
||||
'1969-07-20 00:00',
|
||||
'1969-07-20'
|
||||
];
|
||||
|
||||
let utcFormatter;
|
||||
|
||||
beforeEach(() => {
|
||||
utcFormatter = new UTCTimeFormat();
|
||||
});
|
||||
|
||||
describe('creates a new UTC based formatter', function () {
|
||||
it("with the key 'utc'", () => {
|
||||
expect(utcFormatter.key).toBe(UTC_KEY);
|
||||
});
|
||||
|
||||
it('that will format a timestamp in UTC Standard Date', () => {
|
||||
//default format
|
||||
expect(utcFormatter.format(MOON_LANDING_TIMESTAMP)).toBe(
|
||||
MOON_LANDING_DEFAULT_FORMAT
|
||||
);
|
||||
|
||||
//possible formats
|
||||
const formattedDates = utcFormatter.DATE_FORMATS.map((format) =>
|
||||
utcFormatter.format(MOON_LANDING_TIMESTAMP, format)
|
||||
);
|
||||
|
||||
expect(formattedDates).toEqual(MOON_LANDING_FORMATTED_DATES);
|
||||
});
|
||||
|
||||
it('that will parse an UTC Standard Date into milliseconds', () => {
|
||||
//default format
|
||||
expect(utcFormatter.parse(MOON_LANDING_DEFAULT_FORMAT)).toBe(
|
||||
MOON_LANDING_TIMESTAMP
|
||||
);
|
||||
|
||||
//possible formats
|
||||
const parsedDates = MOON_LANDING_FORMATTED_DATES.map((format) =>
|
||||
utcFormatter.parse(format)
|
||||
);
|
||||
|
||||
parsedDates.forEach((v) => expect(v).toEqual(MOON_LANDING_TIMESTAMP));
|
||||
});
|
||||
|
||||
it('that will validate correctly', () => {
|
||||
//default format
|
||||
expect(utcFormatter.validate(MOON_LANDING_DEFAULT_FORMAT)).toBe(
|
||||
true
|
||||
);
|
||||
|
||||
//possible formats
|
||||
const validatedFormats = MOON_LANDING_FORMATTED_DATES.map((date) =>
|
||||
utcFormatter.validate(date)
|
||||
);
|
||||
|
||||
validatedFormats.forEach((v) => expect(v).toBe(true));
|
||||
|
||||
//junk
|
||||
expect(utcFormatter.validate(JUNK)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
@ -44,13 +44,12 @@ describe('CustomStringFormatter', function () {
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
CUSTOM_FORMATS.forEach(openmct.telemetry.addFormat.bind({openmct}));
|
||||
CUSTOM_FORMATS.forEach((formatter) => {
|
||||
openmct.telemetry.addFormat(formatter);
|
||||
});
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
|
||||
spyOn(openmct.telemetry, 'getFormatter');
|
||||
openmct.telemetry.getFormatter.and.callFake((key) => CUSTOM_FORMATS.find(d => d.key === key));
|
||||
|
||||
customStringFormatter = new CustomStringFormatter(openmct, valueMetadata);
|
||||
});
|
||||
|
||||
|
@ -49,6 +49,7 @@ define([
|
||||
* @memberof platform/commonUI/formats
|
||||
*/
|
||||
function LocalTimeFormat() {
|
||||
this.key = 'local-format';
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,11 +30,7 @@ define([
|
||||
return function () {
|
||||
return function (openmct) {
|
||||
openmct.time.addTimeSystem(new LocalTimeSystem());
|
||||
|
||||
openmct.legacyExtension('formats', {
|
||||
key: 'local-format',
|
||||
implementation: LocalTimeFormat
|
||||
});
|
||||
openmct.telemetry.addFormat(new LocalTimeFormat());
|
||||
};
|
||||
};
|
||||
});
|
||||
|
@ -71,8 +71,7 @@ export default class XAxisModel extends Model {
|
||||
defaults(options) {
|
||||
const bounds = options.openmct.time.bounds();
|
||||
const timeSystem = options.openmct.time.timeSystem();
|
||||
const format = options.openmct.$injector.get('formatService')
|
||||
.getFormat(timeSystem.timeFormat);
|
||||
const format = options.openmct.telemetry.getFormatter(timeSystem.timeFormat);
|
||||
|
||||
return {
|
||||
name: timeSystem.name,
|
||||
|
@ -73,7 +73,6 @@ define([
|
||||
'./hyperlink/plugin',
|
||||
'./clock/plugin',
|
||||
'./DeviceClassifier/plugin',
|
||||
'./UTCTimeFormat/plugin',
|
||||
'./timer/plugin'
|
||||
], function (
|
||||
_,
|
||||
@ -128,7 +127,6 @@ define([
|
||||
Hyperlink,
|
||||
Clock,
|
||||
DeviceClassifier,
|
||||
UTCTimeFormat,
|
||||
Timer
|
||||
) {
|
||||
const bundleMap = {
|
||||
@ -144,7 +142,7 @@ define([
|
||||
};
|
||||
});
|
||||
|
||||
plugins.UTCTimeSystem = UTCTimeSystem;
|
||||
plugins.UTCTimeSystem = UTCTimeSystem.default;
|
||||
plugins.LocalTimeSystem = LocalTimeSystem;
|
||||
plugins.RemoteClock = RemoteClock.default;
|
||||
|
||||
@ -237,7 +235,6 @@ define([
|
||||
plugins.Clock = Clock.default;
|
||||
plugins.Timer = Timer.default;
|
||||
plugins.DeviceClassifier = DeviceClassifier.default;
|
||||
plugins.UTCTimeFormat = UTCTimeFormat.default;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
@ -41,6 +41,7 @@ const LOCAL_STORAGE_HISTORY_KEY_REALTIME = 'tcHistoryRealtime';
|
||||
const DEFAULT_RECORDS = 10;
|
||||
|
||||
import { millisecondsToDHMS } from "utils/duration";
|
||||
import UTCTimeFormat from "../utcTimeSystem/UTCTimeFormat.js";
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'configuration'],
|
||||
@ -263,7 +264,15 @@ export default {
|
||||
format: format
|
||||
}).formatter;
|
||||
|
||||
return (isNegativeOffset ? '-' : '') + formatter.format(time, 'YYYY-MM-DD HH:mm:ss');
|
||||
let formattedDate;
|
||||
|
||||
if (formatter instanceof UTCTimeFormat) {
|
||||
formattedDate = formatter.format(time, formatter.DATE_FORMATS.PRECISION_SECONDS);
|
||||
} else {
|
||||
formattedDate = formatter.format(time);
|
||||
}
|
||||
|
||||
return (isNegativeOffset ? '-' : '') + formattedDate;
|
||||
},
|
||||
showHistoryMenu() {
|
||||
const elementBoundingClientRect = this.$refs.historyButton.getBoundingClientRect();
|
||||
|
37
src/plugins/utcTimeSystem/DurationFormat.js
Normal file
37
src/plugins/utcTimeSystem/DurationFormat.js
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
import moment from 'moment';
|
||||
|
||||
const DATE_FORMAT = "HH:mm:ss";
|
||||
const DATE_FORMATS = [
|
||||
DATE_FORMAT
|
||||
];
|
||||
|
||||
/**
|
||||
* Formatter for duration. Uses moment to produce a date from a given
|
||||
* value, but output is formatted to display only time. Can be used for
|
||||
* specifying a time duration. For specifying duration, it's best to
|
||||
* specify a date of January 1, 1970, as the ms offset will equal the
|
||||
* duration represented by the time.
|
||||
*
|
||||
* @implements {Format}
|
||||
* @constructor
|
||||
* @memberof platform/commonUI/formats
|
||||
*/
|
||||
class DurationFormat {
|
||||
constructor() {
|
||||
this.key = "duration";
|
||||
}
|
||||
format(value) {
|
||||
return moment.utc(value).format(DATE_FORMAT);
|
||||
}
|
||||
|
||||
parse(text) {
|
||||
return moment.duration(text).asMilliseconds();
|
||||
}
|
||||
|
||||
validate(text) {
|
||||
return moment.utc(text, DATE_FORMATS, true).isValid();
|
||||
}
|
||||
}
|
||||
|
||||
export default DurationFormat;
|
@ -34,39 +34,39 @@ export default class UTCTimeFormat {
|
||||
constructor() {
|
||||
this.key = 'utc';
|
||||
this.DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss.SSS';
|
||||
this.DATE_FORMATS = [
|
||||
this.DATE_FORMAT,
|
||||
this.DATE_FORMAT + 'Z',
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
'YYYY-MM-DD HH:mm',
|
||||
'YYYY-MM-DD'
|
||||
];
|
||||
this.DATE_FORMATS = {
|
||||
PRECISION_DEFAULT: this.DATE_FORMAT,
|
||||
PRECISION_DEFAULT_WITH_ZULU: this.DATE_FORMAT + 'Z',
|
||||
PRECISION_SECONDS: 'YYYY-MM-DD HH:mm:ss',
|
||||
PRECISION_MINUTES: 'YYYY-MM-DD HH:mm',
|
||||
PRECISION_DAYS: 'YYYY-MM-DD'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} formatString
|
||||
* @returns the value of formatString if the value is a string type and exists in the DATE_FORMATS array; otherwise the DATE_FORMAT value.
|
||||
*/
|
||||
validateFormatString(formatString) {
|
||||
return typeof formatString === 'string'
|
||||
&& this.DATE_FORMATS.includes(formatString)
|
||||
? formatString
|
||||
: this.DATE_FORMAT;
|
||||
isValidFormatString(formatString) {
|
||||
return Object.values(this.DATE_FORMATS).includes(formatString);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value The value to format.
|
||||
* @param {string} formatString The string format to format. Default "YYYY-MM-DD HH:mm:ss.SSS" + "Z"
|
||||
* @returns {string} the formatted date(s) according to the proper parameter of formatString or the default value of "YYYY-MM-DD HH:mm:ss.SSS" + "Z".
|
||||
* If multiple values were requested, then an array of
|
||||
* @returns {string} the formatted date(s). If multiple values were requested, then an array of
|
||||
* formatted values will be returned. Where a value could not be formatted, `undefined` will be returned at its position
|
||||
* in the array.
|
||||
*/
|
||||
format(value, formatString) {
|
||||
if (value !== undefined) {
|
||||
const format = this.validateFormatString(formatString);
|
||||
const utc = moment.utc(value);
|
||||
|
||||
if (formatString !== undefined && !this.isValidFormatString(formatString)) {
|
||||
throw "Invalid format requested from UTC Time Formatter ";
|
||||
}
|
||||
|
||||
let format = formatString || this.DATE_FORMATS.PRECISION_DEFAULT;
|
||||
|
||||
return utc.format(format) + (formatString ? '' : 'Z');
|
||||
} else {
|
||||
return value;
|
||||
@ -78,10 +78,11 @@ export default class UTCTimeFormat {
|
||||
return text;
|
||||
}
|
||||
|
||||
return moment.utc(text, this.DATE_FORMATS).valueOf();
|
||||
return moment.utc(text, Object.values(this.DATE_FORMATS)).valueOf();
|
||||
}
|
||||
|
||||
validate(text) {
|
||||
return moment.utc(text, this.DATE_FORMATS, true).isValid();
|
||||
return moment.utc(text, Object.values(this.DATE_FORMATS), true).isValid();
|
||||
}
|
||||
|
||||
}
|
@ -20,22 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./UTCTimeSystem",
|
||||
"./LocalClock"
|
||||
], function (
|
||||
UTCTimeSystem,
|
||||
LocalClock
|
||||
) {
|
||||
/**
|
||||
* Install a time system that supports UTC times. It also installs a local
|
||||
* clock source that ticks every 100ms, providing UTC times.
|
||||
*/
|
||||
return function () {
|
||||
return function (openmct) {
|
||||
const timeSystem = new UTCTimeSystem();
|
||||
openmct.time.addTimeSystem(timeSystem);
|
||||
openmct.time.addClock(new LocalClock.default(100));
|
||||
};
|
||||
import UTCTimeSystem from './UTCTimeSystem';
|
||||
import LocalClock from './LocalClock';
|
||||
import UTCTimeFormat from './UTCTimeFormat';
|
||||
import DurationFormat from './DurationFormat';
|
||||
|
||||
/**
|
||||
* Install a time system that supports UTC times. It also installs a local
|
||||
* clock source that ticks every 100ms, providing UTC times.
|
||||
*/
|
||||
export default function () {
|
||||
return function (openmct) {
|
||||
const timeSystem = new UTCTimeSystem();
|
||||
openmct.time.addTimeSystem(timeSystem);
|
||||
openmct.time.addClock(new LocalClock(100));
|
||||
openmct.telemetry.addFormat(new UTCTimeFormat());
|
||||
openmct.telemetry.addFormat(new DurationFormat());
|
||||
};
|
||||
});
|
||||
}
|
||||
|
@ -26,9 +26,11 @@ import {
|
||||
createOpenMct,
|
||||
resetApplicationState
|
||||
} from 'utils/testing';
|
||||
import UTCTimeFormat from './UTCTimeFormat.js';
|
||||
|
||||
describe("The UTC Time System", () => {
|
||||
const UTC_SYSTEM_AND_FORMAT_KEY = 'utc';
|
||||
const DURATION_FORMAT_KEY = 'duration';
|
||||
let openmct;
|
||||
let utcTimeSystem;
|
||||
let mockTimeout;
|
||||
@ -100,4 +102,93 @@ describe("The UTC Time System", () => {
|
||||
expect(mockListener).toHaveBeenCalledWith(jasmine.any(Number));
|
||||
});
|
||||
});
|
||||
|
||||
describe("UTC Time Format", () => {
|
||||
let utcTimeFormatter;
|
||||
|
||||
beforeEach(() => {
|
||||
utcTimeFormatter = openmct.telemetry.getFormatter(UTC_SYSTEM_AND_FORMAT_KEY);
|
||||
});
|
||||
|
||||
it("is installed by the plugin", () => {
|
||||
expect(utcTimeFormatter).toBeDefined();
|
||||
});
|
||||
|
||||
it("formats from ms since Unix epoch into Open MCT UTC time format", () => {
|
||||
const TIME_IN_MS = 1638574560945;
|
||||
const TIME_AS_STRING = "2021-12-03 23:36:00.945Z";
|
||||
|
||||
const formattedTime = utcTimeFormatter.format(TIME_IN_MS);
|
||||
expect(formattedTime).toEqual(TIME_AS_STRING);
|
||||
|
||||
});
|
||||
|
||||
it("formats from ms since Unix epoch into terse UTC formats", () => {
|
||||
const utcTimeFormatterInstance = new UTCTimeFormat();
|
||||
|
||||
const TIME_IN_MS = 1638574560945;
|
||||
const EXPECTED_FORMATS = {
|
||||
PRECISION_DEFAULT: "2021-12-03 23:36:00.945",
|
||||
PRECISION_SECONDS: "2021-12-03 23:36:00",
|
||||
PRECISION_MINUTES: "2021-12-03 23:36",
|
||||
PRECISION_DAYS: "2021-12-03"
|
||||
};
|
||||
|
||||
Object.keys(EXPECTED_FORMATS).forEach((formatKey) => {
|
||||
const formattedTime = utcTimeFormatterInstance.format(TIME_IN_MS, utcTimeFormatterInstance.DATE_FORMATS[formatKey]);
|
||||
expect(formattedTime).toEqual(EXPECTED_FORMATS[formatKey]);
|
||||
});
|
||||
});
|
||||
|
||||
it("parses from Open MCT UTC time format to ms since Unix epoch.", () => {
|
||||
const TIME_IN_MS = 1638574560945;
|
||||
const TIME_AS_STRING = "2021-12-03 23:36:00.945Z";
|
||||
|
||||
const parsedTime = utcTimeFormatter.parse(TIME_AS_STRING);
|
||||
expect(parsedTime).toEqual(TIME_IN_MS);
|
||||
});
|
||||
|
||||
it("validates correctly formatted Open MCT UTC times.", () => {
|
||||
const TIME_AS_STRING = "2021-12-03 23:36:00.945Z";
|
||||
|
||||
const isValid = utcTimeFormatter.validate(TIME_AS_STRING);
|
||||
expect(isValid).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Duration Format", () => {
|
||||
let durationTimeFormatter;
|
||||
|
||||
beforeEach(() => {
|
||||
durationTimeFormatter = openmct.telemetry.getFormatter(DURATION_FORMAT_KEY);
|
||||
});
|
||||
|
||||
it("is installed by the plugin", () => {
|
||||
expect(durationTimeFormatter).toBeDefined();
|
||||
});
|
||||
|
||||
it("formats from ms into Open MCT duration format", () => {
|
||||
const TIME_IN_MS = 2000;
|
||||
const TIME_AS_STRING = "00:00:02";
|
||||
|
||||
const formattedTime = durationTimeFormatter.format(TIME_IN_MS);
|
||||
expect(formattedTime).toEqual(TIME_AS_STRING);
|
||||
|
||||
});
|
||||
|
||||
it("parses from Open MCT duration format to ms", () => {
|
||||
const TIME_IN_MS = 2000;
|
||||
const TIME_AS_STRING = "00:00:02";
|
||||
|
||||
const parsedTime = durationTimeFormatter.parse(TIME_AS_STRING);
|
||||
expect(parsedTime).toEqual(TIME_IN_MS);
|
||||
});
|
||||
|
||||
it("validates correctly formatted Open MCT duration strings.", () => {
|
||||
const TIME_AS_STRING = "00:00:02";
|
||||
|
||||
const isValid = durationTimeFormatter.validate(TIME_AS_STRING);
|
||||
expect(isValid).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Reference in New Issue
Block a user