mirror of
https://github.com/nasa/openmct.git
synced 2024-12-24 07:16:39 +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:
parent
01d02642e8
commit
fd0e89ca05
4
API.md
4
API.md
@ -27,7 +27,7 @@
|
||||
- [Request Strategies **draft**](#request-strategies-draft)
|
||||
- [`latest` request strategy](#latest-request-strategy)
|
||||
- [`minmax` request strategy](#minmax-request-strategy)
|
||||
- [Telemetry Formats **draft**](#telemetry-formats-draft)
|
||||
- [Telemetry Formats](#telemetry-formats)
|
||||
- [Registering Formats](#registering-formats)
|
||||
- [Telemetry Data](#telemetry-data)
|
||||
- [Telemetry Datums](#telemetry-datums)
|
||||
@ -525,7 +525,7 @@ example:
|
||||
|
||||
MinMax queries are issued by plots, and may be issued by other types as well. The aim is to reduce the amount of data returned but still faithfully represent the full extent of the data. In order to do this, the view calculates the maximum data resolution it can display (i.e. the number of horizontal pixels in a plot) and sends that as the `size`. The response should include at least one minimum and one maximum value per point of resolution.
|
||||
|
||||
#### Telemetry Formats **draft**
|
||||
#### Telemetry Formats
|
||||
|
||||
Telemetry format objects define how to interpret and display telemetry data.
|
||||
They have a simple structure:
|
||||
|
@ -1,72 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/FormatProvider",
|
||||
"./src/DurationFormat"
|
||||
], function (
|
||||
FormatProvider,
|
||||
DurationFormat
|
||||
) {
|
||||
return {
|
||||
name: "platform/commonUI/formats",
|
||||
definition: {
|
||||
"name": "Format Registry",
|
||||
"description": "Provides a registry for formats, which allow parsing and formatting of values.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"provides": "formatService",
|
||||
"type": "provider",
|
||||
"implementation": FormatProvider,
|
||||
"depends": [
|
||||
"formats[]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
{
|
||||
"key": "duration",
|
||||
"implementation": DurationFormat
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "DEFAULT_TIME_FORMAT",
|
||||
"value": "utc"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"name": "d3",
|
||||
"version": "3.0.0",
|
||||
"description": "Incorporates modified code from d3 Time Scales",
|
||||
"author": "Mike Bostock",
|
||||
"copyright": "Copyright 2010-2016 Mike Bostock. "
|
||||
+ "All rights reserved.",
|
||||
"link": "https://github.com/d3/d3/blob/master/LICENSE"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
@ -1,62 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'moment'
|
||||
], function (
|
||||
moment
|
||||
) {
|
||||
|
||||
var DATE_FORMAT = "HH:mm:ss",
|
||||
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
|
||||
*/
|
||||
function DurationFormat() {
|
||||
this.key = "duration";
|
||||
}
|
||||
|
||||
DurationFormat.prototype.format = function (value) {
|
||||
return moment.utc(value).format(DATE_FORMAT);
|
||||
};
|
||||
|
||||
DurationFormat.prototype.parse = function (text) {
|
||||
return moment.duration(text).asMilliseconds();
|
||||
};
|
||||
|
||||
DurationFormat.prototype.validate = function (text) {
|
||||
return moment.utc(text, DATE_FORMATS, true).isValid();
|
||||
};
|
||||
|
||||
return DurationFormat;
|
||||
});
|
@ -1,123 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
|
||||
], function (
|
||||
|
||||
) {
|
||||
|
||||
/**
|
||||
* An object used to convert between numeric values and text values,
|
||||
* typically used to display these values to the user and to convert
|
||||
* user input to a numeric format, particularly for time formats.
|
||||
* @interface Format
|
||||
*/
|
||||
/**
|
||||
* Parse text (typically user input) to a numeric value.
|
||||
* Behavior is undefined when the text cannot be parsed;
|
||||
* `validate` should be called first if the text may be invalid.
|
||||
* @method Format#parse
|
||||
* @memberof Format#
|
||||
* @param {string} text the text to parse
|
||||
* @returns {number} the parsed numeric value
|
||||
*/
|
||||
|
||||
/**
|
||||
* @property {string} key A unique identifier for this formatter.
|
||||
* @memberof Format#
|
||||
*/
|
||||
|
||||
/**
|
||||
* Determine whether or not some text (typically user input) can
|
||||
* be parsed to a numeric value by this format.
|
||||
* @method validate
|
||||
* @memberof Format#
|
||||
* @param {string} text the text to parse
|
||||
* @returns {boolean} true if the text can be parsed
|
||||
*/
|
||||
|
||||
/**
|
||||
* Convert a numeric value to a text value for display using
|
||||
* this format.
|
||||
* @method format
|
||||
* @memberof Format#
|
||||
* @param {number} value the numeric value to format
|
||||
* @param {number} [minValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||
* and plot axes. Specifies the smallest number on the scale.
|
||||
* @param {number} [maxValue] Contextual information for scaled formatting used in linear scales such as conductor
|
||||
* and plot axes. Specifies the largest number on the scale
|
||||
* @param {number} [count] Contextual information for scaled formatting used in linear scales such as conductor
|
||||
* and plot axes. The number of labels on the scale.
|
||||
* @returns {string} the text representation of the value
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides access to `Format` objects which can be used to
|
||||
* convert values between human-readable text and numeric
|
||||
* representations.
|
||||
* @interface FormatService
|
||||
*/
|
||||
|
||||
/**
|
||||
* Look up a format by its symbolic identifier.
|
||||
* @method getFormat
|
||||
* @memberof FormatService#
|
||||
* @param {string} key the identifier for this format
|
||||
* @returns {Format} the format
|
||||
* @throws {Error} errors when the requested format is unrecognized
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provides formats from the `formats` extension category.
|
||||
* @constructor
|
||||
* @implements {FormatService}
|
||||
* @memberof platform/commonUI/formats
|
||||
* @param {Array.<function(new : Format)>} format constructors,
|
||||
* from the `formats` extension category.
|
||||
*/
|
||||
function FormatProvider(formats) {
|
||||
var formatMap = {};
|
||||
|
||||
function addToMap(Format) {
|
||||
var key = Format.key;
|
||||
if (key && !formatMap[key]) {
|
||||
formatMap[key] = new Format();
|
||||
}
|
||||
}
|
||||
|
||||
formats.forEach(addToMap);
|
||||
this.formatMap = formatMap;
|
||||
}
|
||||
|
||||
FormatProvider.prototype.getFormat = function (key) {
|
||||
var format = this.formatMap[key];
|
||||
if (!format) {
|
||||
throw new Error("FormatProvider: No format found for " + key);
|
||||
}
|
||||
|
||||
return format;
|
||||
};
|
||||
|
||||
return FormatProvider;
|
||||
|
||||
});
|
@ -1,69 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['../src/FormatProvider'],
|
||||
function (FormatProvider) {
|
||||
|
||||
var KEYS = ['a', 'b', 'c'];
|
||||
|
||||
describe("The FormatProvider", function () {
|
||||
var mockFormats,
|
||||
mockFormatInstances,
|
||||
provider;
|
||||
|
||||
beforeEach(function () {
|
||||
mockFormatInstances = KEYS.map(function (k) {
|
||||
return jasmine.createSpyObj(
|
||||
'format-' + k,
|
||||
['parse', 'validate', 'format']
|
||||
);
|
||||
});
|
||||
// Return constructors
|
||||
mockFormats = KEYS.map(function (k, i) {
|
||||
function MockFormat() {
|
||||
return mockFormatInstances[i];
|
||||
}
|
||||
|
||||
MockFormat.key = k;
|
||||
|
||||
return MockFormat;
|
||||
});
|
||||
provider = new FormatProvider(mockFormats);
|
||||
});
|
||||
|
||||
it("looks up formats by key", function () {
|
||||
KEYS.forEach(function (k, i) {
|
||||
expect(provider.getFormat(k))
|
||||
.toEqual(mockFormatInstances[i]);
|
||||
});
|
||||
});
|
||||
|
||||
it("throws an error about unknown formats", function () {
|
||||
expect(function () {
|
||||
provider.getFormat('some-unknown-format');
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -299,7 +299,6 @@ define([
|
||||
this.install(this.plugins.ObjectInterceptors());
|
||||
this.install(this.plugins.NonEditableFolder());
|
||||
this.install(this.plugins.DeviceClassifier());
|
||||
this.install(this.plugins.UTCTimeFormat());
|
||||
}
|
||||
|
||||
MCT.prototype = Object.create(EventEmitter.prototype);
|
||||
|
@ -9,7 +9,7 @@ describe("Transaction Class", () => {
|
||||
beforeEach(() => {
|
||||
objectAPI = {
|
||||
makeKeyString: (identifier) => utils.makeKeyString(identifier),
|
||||
save: (object) => object,
|
||||
save: (object) => Promise.resolve(object),
|
||||
mutate: (object, prop, value) => {
|
||||
object[prop] = value;
|
||||
|
||||
@ -60,7 +60,7 @@ describe("Transaction Class", () => {
|
||||
mockDomainObjects.forEach(transaction.add.bind(transaction));
|
||||
|
||||
expect(transaction.dirtyObjects.size).toEqual(3);
|
||||
spyOn(objectAPI, 'save');
|
||||
spyOn(objectAPI, 'save').and.callThrough();
|
||||
transaction.commit()
|
||||
.then(success => {
|
||||
expect(transaction.dirtyObjects.size).toEqual(0);
|
||||
|
@ -144,6 +144,7 @@ define([
|
||||
this.metadataCache = new WeakMap();
|
||||
this.formatMapCache = new WeakMap();
|
||||
this.valueFormatterCache = new WeakMap();
|
||||
this.formatters = new Map();
|
||||
this.requestAbortControllers = new Set();
|
||||
}
|
||||
|
||||
@ -445,17 +446,6 @@ define([
|
||||
return _.sortBy(options, sortKeys);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
TelemetryAPI.prototype.getFormatService = function () {
|
||||
if (!this.formatService) {
|
||||
this.formatService = this.openmct.$injector.get('formatService');
|
||||
}
|
||||
|
||||
return this.formatService;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a value formatter for a given valueMetadata.
|
||||
*
|
||||
@ -465,7 +455,7 @@ define([
|
||||
if (!this.valueFormatterCache.has(valueMetadata)) {
|
||||
this.valueFormatterCache.set(
|
||||
valueMetadata,
|
||||
new TelemetryValueFormatter(valueMetadata, this.getFormatService())
|
||||
new TelemetryValueFormatter(valueMetadata, this.formatters)
|
||||
);
|
||||
}
|
||||
|
||||
@ -479,9 +469,7 @@ define([
|
||||
* @returns {Format}
|
||||
*/
|
||||
TelemetryAPI.prototype.getFormatter = function (key) {
|
||||
const formatMap = this.getFormatService().formatMap;
|
||||
|
||||
return formatMap[key];
|
||||
return this.formatters.get(key);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -512,12 +500,7 @@ define([
|
||||
* @param {Format} format the
|
||||
*/
|
||||
TelemetryAPI.prototype.addFormat = function (format) {
|
||||
this.openmct.legacyExtension('formats', {
|
||||
key: format.key,
|
||||
implementation: function () {
|
||||
return format;
|
||||
}
|
||||
});
|
||||
this.formatters.set(format.key, format);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@ define([
|
||||
) {
|
||||
|
||||
// TODO: needs reference to formatService;
|
||||
function TelemetryValueFormatter(valueMetadata, formatService) {
|
||||
function TelemetryValueFormatter(valueMetadata, formatMap) {
|
||||
const numberFormatter = {
|
||||
parse: function (x) {
|
||||
return Number(x);
|
||||
@ -43,13 +43,7 @@ define([
|
||||
};
|
||||
|
||||
this.valueMetadata = valueMetadata;
|
||||
try {
|
||||
this.formatter = formatService
|
||||
.getFormat(valueMetadata.format, valueMetadata);
|
||||
} catch (e) {
|
||||
// TODO: Better formatting
|
||||
this.formatter = numberFormatter;
|
||||
}
|
||||
this.formatter = formatMap.get(valueMetadata.format) || numberFormatter;
|
||||
|
||||
if (valueMetadata.format === 'enum') {
|
||||
this.formatter = {};
|
||||
|
@ -27,7 +27,6 @@ const DEFAULTS = [
|
||||
'platform/commonUI/browse',
|
||||
'platform/commonUI/edit',
|
||||
'platform/commonUI/dialog',
|
||||
'platform/commonUI/formats',
|
||||
'platform/commonUI/general',
|
||||
'platform/commonUI/inspect',
|
||||
'platform/commonUI/mobile',
|
||||
@ -60,7 +59,6 @@ define([
|
||||
'../platform/commonUI/browse/bundle',
|
||||
'../platform/commonUI/dialog/bundle',
|
||||
'../platform/commonUI/edit/bundle',
|
||||
'../platform/commonUI/formats/bundle',
|
||||
'../platform/commonUI/general/bundle',
|
||||
'../platform/commonUI/inspect/bundle',
|
||||
'../platform/commonUI/mobile/bundle',
|
||||
|
@ -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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user