mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 05:37:53 +00:00
Reduce bundle size (#7246)
* chore: use ESModule imports for d3 libraries * chore: add d3 types * chore: use minified plotly * chore: use ESModule style imports for printj * chore: use `terser-webpack-plugin` to minimize * Revert "chore: use minified plotly" This reverts commit 0ae9b39d41b6e38f0fe38cd89a2cd73869f31c36. * Revert "Revert "chore: use minified plotly"" This reverts commit 08973a2d2e6675206907f678d447717ac6526613. * fix: use default minification options * test: stabilize notebook image drop e2e test * test(fix): remove .only() * refactor: convert TelemetryValueFormatter to es6 class --------- Co-authored-by: Scott Bell <scott@traclabs.com>
This commit is contained in:
parent
0d97675a0a
commit
715a44864e
@ -69,9 +69,9 @@ const config = {
|
|||||||
csv: 'comma-separated-values',
|
csv: 'comma-separated-values',
|
||||||
EventEmitter: 'eventemitter3',
|
EventEmitter: 'eventemitter3',
|
||||||
bourbon: 'bourbon.scss',
|
bourbon: 'bourbon.scss',
|
||||||
'plotly-basic': 'plotly.js-basic-dist',
|
'plotly-basic': 'plotly.js-basic-dist-min',
|
||||||
'plotly-gl2d': 'plotly.js-gl2d-dist',
|
'plotly-gl2d': 'plotly.js-gl2d-dist-min',
|
||||||
printj: path.join(projectRootDir, 'node_modules/printj/dist/printj.min.js'),
|
printj: 'printj/printj.mjs',
|
||||||
styles: path.join(projectRootDir, 'src/styles'),
|
styles: path.join(projectRootDir, 'src/styles'),
|
||||||
MCT: path.join(projectRootDir, 'src/MCT'),
|
MCT: path.join(projectRootDir, 'src/MCT'),
|
||||||
testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'),
|
testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'),
|
||||||
|
@ -19,12 +19,13 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
/* global __dirname */
|
||||||
/*
|
/*
|
||||||
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks.
|
This test suite is dedicated to tests which verify the basic operations surrounding Notebooks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs').promises;
|
const fs = require('fs').promises;
|
||||||
|
const path = require('path');
|
||||||
const { test, expect } = require('../../../../pluginFixtures');
|
const { test, expect } = require('../../../../pluginFixtures');
|
||||||
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
const { createDomainObjectWithDefaults } = require('../../../../appActions');
|
||||||
|
|
||||||
@ -176,7 +177,9 @@ test.describe('Snapshot image tests', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('Can drop an image onto a notebook and create a new entry', async ({ page }) => {
|
test('Can drop an image onto a notebook and create a new entry', async ({ page }) => {
|
||||||
const imageData = await fs.readFile('src/images/favicons/favicon-96x96.png');
|
const imageData = await fs.readFile(
|
||||||
|
path.resolve(__dirname, '../../../../../src/images/favicons/favicon-96x96.png')
|
||||||
|
);
|
||||||
const imageArray = new Uint8Array(imageData);
|
const imageArray = new Uint8Array(imageData);
|
||||||
const fileData = Array.from(imageArray);
|
const fileData = Array.from(imageArray);
|
||||||
|
|
||||||
@ -201,14 +204,17 @@ test.describe('Snapshot image tests', () => {
|
|||||||
// drop another image onto the entry
|
// drop another image onto the entry
|
||||||
await page.dispatchEvent('.c-snapshots', 'drop', { dataTransfer: dropTransfer });
|
await page.dispatchEvent('.c-snapshots', 'drop', { dataTransfer: dropTransfer });
|
||||||
|
|
||||||
|
const secondThumbnail = page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).nth(1);
|
||||||
|
await secondThumbnail.waitFor({ state: 'attached' });
|
||||||
// expect two embedded images now
|
// expect two embedded images now
|
||||||
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(2);
|
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(2);
|
||||||
|
|
||||||
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
await page.locator('.c-snapshot.c-ne__embed').first().getByTitle('More options').click();
|
||||||
|
|
||||||
await page.getByRole('menuitem', { name: /Remove This Embed/ }).click();
|
await page.getByRole('menuitem', { name: /Remove This Embed/ }).click();
|
||||||
|
|
||||||
await page.getByRole('button', { name: 'Ok', exact: true }).click();
|
await page.getByRole('button', { name: 'Ok', exact: true }).click();
|
||||||
|
// Ensure that the thumbnail is removed before we assert
|
||||||
|
await secondThumbnail.waitFor({ state: 'detached' });
|
||||||
|
|
||||||
// expect one embedded image now as we deleted the other
|
// expect one embedded image now as we deleted the other
|
||||||
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(1);
|
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(1);
|
||||||
|
@ -11,6 +11,9 @@
|
|||||||
"@percy/cli": "1.27.4",
|
"@percy/cli": "1.27.4",
|
||||||
"@percy/playwright": "1.0.4",
|
"@percy/playwright": "1.0.4",
|
||||||
"@playwright/test": "1.39.0",
|
"@playwright/test": "1.39.0",
|
||||||
|
"@types/d3-axis": "3.0.6",
|
||||||
|
"@types/d3-scale": "4.0.8",
|
||||||
|
"@types/d3-selection": "3.0.10",
|
||||||
"@types/eventemitter3": "1.2.0",
|
"@types/eventemitter3": "1.2.0",
|
||||||
"@types/jasmine": "5.1.2",
|
"@types/jasmine": "5.1.2",
|
||||||
"@types/lodash": "4.14.192",
|
"@types/lodash": "4.14.192",
|
||||||
@ -62,8 +65,8 @@
|
|||||||
"npm-run-all2": "6.1.1",
|
"npm-run-all2": "6.1.1",
|
||||||
"nyc": "15.1.0",
|
"nyc": "15.1.0",
|
||||||
"painterro": "1.2.87",
|
"painterro": "1.2.87",
|
||||||
"plotly.js-basic-dist": "2.20.0",
|
"plotly.js-basic-dist-min": "2.20.0",
|
||||||
"plotly.js-gl2d-dist": "2.20.0",
|
"plotly.js-gl2d-dist-min": "2.20.0",
|
||||||
"prettier": "2.8.7",
|
"prettier": "2.8.7",
|
||||||
"printj": "1.3.1",
|
"printj": "1.3.1",
|
||||||
"resolve-url-loader": "5.0.0",
|
"resolve-url-loader": "5.0.0",
|
||||||
@ -72,6 +75,7 @@
|
|||||||
"sass-loader": "13.3.2",
|
"sass-loader": "13.3.2",
|
||||||
"sinon": "17.0.0",
|
"sinon": "17.0.0",
|
||||||
"style-loader": "3.3.3",
|
"style-loader": "3.3.3",
|
||||||
|
"terser-webpack-plugin": "5.3.9",
|
||||||
"tiny-emitter": "2.1.0",
|
"tiny-emitter": "2.1.0",
|
||||||
"typescript": "5.2.2",
|
"typescript": "5.2.2",
|
||||||
"uuid": "9.0.1",
|
"uuid": "9.0.1",
|
||||||
|
@ -20,39 +20,25 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(['lodash', 'printj'], function (_, printj) {
|
import _ from 'lodash';
|
||||||
|
import { sprintf } from 'printj';
|
||||||
|
|
||||||
// TODO: needs reference to formatService;
|
// TODO: needs reference to formatService;
|
||||||
function TelemetryValueFormatter(valueMetadata, formatMap) {
|
export default class TelemetryValueFormatter {
|
||||||
|
constructor(valueMetadata, formatMap) {
|
||||||
|
this.valueMetadata = valueMetadata;
|
||||||
|
this.formatMap = formatMap;
|
||||||
|
this.valueMetadataFormat = this.getNonArrayValue(valueMetadata.format);
|
||||||
|
|
||||||
const numberFormatter = {
|
const numberFormatter = {
|
||||||
parse: function (x) {
|
parse: (x) => Number(x),
|
||||||
return Number(x);
|
format: (x) => x,
|
||||||
},
|
validate: (x) => true
|
||||||
format: function (x) {
|
|
||||||
return x;
|
|
||||||
},
|
|
||||||
validate: function (x) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.valueMetadata = valueMetadata;
|
|
||||||
|
|
||||||
function getNonArrayValue(value) {
|
|
||||||
//metadata format could have array formats ex. string[]/number[]
|
|
||||||
const arrayRegex = /\[\]$/g;
|
|
||||||
if (value && value.match(arrayRegex)) {
|
|
||||||
return value.replace(arrayRegex, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
let valueMetadataFormat = getNonArrayValue(valueMetadata.format);
|
|
||||||
|
|
||||||
// Is there an existing formatter for the format specified? If not, default to number format
|
// Is there an existing formatter for the format specified? If not, default to number format
|
||||||
this.formatter = formatMap.get(valueMetadataFormat) || numberFormatter;
|
this.formatter = formatMap.get(this.valueMetadataFormat) || numberFormatter;
|
||||||
|
if (this.valueMetadataFormat === 'enum') {
|
||||||
if (valueMetadataFormat === 'enum') {
|
|
||||||
this.formatter = {};
|
this.formatter = {};
|
||||||
this.enumerations = valueMetadata.enumerations.reduce(
|
this.enumerations = valueMetadata.enumerations.reduce(
|
||||||
function (vm, e) {
|
function (vm, e) {
|
||||||
@ -66,14 +52,14 @@ define(['lodash', 'printj'], function (_, printj) {
|
|||||||
byString: {}
|
byString: {}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
this.formatter.format = function (value) {
|
this.formatter.format = (value) => {
|
||||||
if (Object.prototype.hasOwnProperty.call(this.enumerations.byValue, value)) {
|
if (Object.prototype.hasOwnProperty.call(this.enumerations.byValue, value)) {
|
||||||
return this.enumerations.byValue[value];
|
return this.enumerations.byValue[value];
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}.bind(this);
|
};
|
||||||
this.formatter.parse = function (string) {
|
this.formatter.parse = (string) => {
|
||||||
if (typeof string === 'string') {
|
if (typeof string === 'string') {
|
||||||
if (Object.prototype.hasOwnProperty.call(this.enumerations.byString, string)) {
|
if (Object.prototype.hasOwnProperty.call(this.enumerations.byString, string)) {
|
||||||
return this.enumerations.byString[string];
|
return this.enumerations.byString[string];
|
||||||
@ -81,19 +67,19 @@ define(['lodash', 'printj'], function (_, printj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Number(string);
|
return Number(string);
|
||||||
}.bind(this);
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for formatString support once instead of per format call.
|
// Check for formatString support once instead of per format call.
|
||||||
if (valueMetadata.formatString) {
|
if (valueMetadata.formatString) {
|
||||||
const baseFormat = this.formatter.format;
|
const baseFormat = this.formatter.format;
|
||||||
const formatString = getNonArrayValue(valueMetadata.formatString);
|
const formatString = this.getNonArrayValue(valueMetadata.formatString);
|
||||||
this.formatter.format = function (value) {
|
this.formatter.format = function (value) {
|
||||||
return printj.sprintf(formatString, baseFormat.call(this, value));
|
return sprintf(formatString, baseFormat.call(this, value));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valueMetadataFormat === 'string') {
|
if (this.valueMetadataFormat === 'string') {
|
||||||
this.formatter.parse = function (value) {
|
this.formatter.parse = function (value) {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
return '';
|
return '';
|
||||||
@ -116,7 +102,17 @@ define(['lodash', 'printj'], function (_, printj) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TelemetryValueFormatter.prototype.parse = function (datum) {
|
getNonArrayValue(value) {
|
||||||
|
//metadata format could have array formats ex. string[]/number[]
|
||||||
|
const arrayRegex = /\[\]$/g;
|
||||||
|
if (value && value.match(arrayRegex)) {
|
||||||
|
return value.replace(arrayRegex, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(datum) {
|
||||||
const isDatumArray = Array.isArray(datum);
|
const isDatumArray = Array.isArray(datum);
|
||||||
if (_.isObject(datum)) {
|
if (_.isObject(datum)) {
|
||||||
const objectDatum = isDatumArray ? datum : datum[this.valueMetadata.source];
|
const objectDatum = isDatumArray ? datum : datum[this.valueMetadata.source];
|
||||||
@ -130,9 +126,9 @@ define(['lodash', 'printj'], function (_, printj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.formatter.parse(datum);
|
return this.formatter.parse(datum);
|
||||||
};
|
}
|
||||||
|
|
||||||
TelemetryValueFormatter.prototype.format = function (datum) {
|
format(datum) {
|
||||||
const isDatumArray = Array.isArray(datum);
|
const isDatumArray = Array.isArray(datum);
|
||||||
if (_.isObject(datum)) {
|
if (_.isObject(datum)) {
|
||||||
const objectDatum = isDatumArray ? datum : datum[this.valueMetadata.source];
|
const objectDatum = isDatumArray ? datum : datum[this.valueMetadata.source];
|
||||||
@ -146,7 +142,5 @@ define(['lodash', 'printj'], function (_, printj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return this.formatter.format(datum);
|
return this.formatter.format(datum);
|
||||||
};
|
}
|
||||||
|
}
|
||||||
return TelemetryValueFormatter;
|
|
||||||
});
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import printj from 'printj';
|
import { sprintf } from 'printj';
|
||||||
|
|
||||||
export default class CustomStringFormatter {
|
export default class CustomStringFormatter {
|
||||||
constructor(openmct, valueMetadata, itemFormat) {
|
constructor(openmct, valueMetadata, itemFormat) {
|
||||||
@ -14,7 +14,7 @@ export default class CustomStringFormatter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.itemFormat.startsWith('&')) {
|
if (!this.itemFormat.startsWith('&')) {
|
||||||
return printj.sprintf(this.itemFormat, datum[this.valueMetadata.key]);
|
return sprintf(this.itemFormat, datum[this.valueMetadata.key]);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as d3Axis from 'd3-axis';
|
import { axisTop } from 'd3-axis';
|
||||||
import { scaleLinear, scaleUtc } from 'd3-scale';
|
import { scaleLinear, scaleUtc } from 'd3-scale';
|
||||||
import * as d3Selection from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
|
|
||||||
import { TIME_CONTEXT_EVENTS } from '../../api/time/constants';
|
import { TIME_CONTEXT_EVENTS } from '../../api/time/constants';
|
||||||
import utcMultiTimeFormat from './utcMultiTimeFormat.js';
|
import utcMultiTimeFormat from './utcMultiTimeFormat.js';
|
||||||
@ -78,9 +78,9 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
let vis = d3Selection.select(this.$refs.axisHolder).append('svg:svg');
|
let vis = select(this.$refs.axisHolder).append('svg:svg');
|
||||||
|
|
||||||
this.xAxis = d3Axis.axisTop();
|
this.xAxis = axisTop();
|
||||||
this.dragging = false;
|
this.dragging = false;
|
||||||
|
|
||||||
// draw x axis with labels. CSS is used to position them.
|
// draw x axis with labels. CSS is used to position them.
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import * as d3Axis from 'd3-axis';
|
import { axisTop } from 'd3-axis';
|
||||||
import { scaleLinear, scaleUtc } from 'd3-scale';
|
import { scaleLinear, scaleUtc } from 'd3-scale';
|
||||||
import * as d3Selection from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
|
|
||||||
import utcMultiTimeFormat from '@/plugins/timeConductor/utcMultiTimeFormat';
|
import utcMultiTimeFormat from '@/plugins/timeConductor/utcMultiTimeFormat';
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ export default {
|
|||||||
this.useSVG = true;
|
this.useSVG = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.container = d3Selection.select(this.$refs.axisHolder);
|
this.container = select(this.$refs.axisHolder);
|
||||||
this.svgElement = this.container.append('svg:svg');
|
this.svgElement = this.container.append('svg:svg');
|
||||||
// draw x axis with labels. CSS is used to position them.
|
// draw x axis with labels. CSS is used to position them.
|
||||||
this.axisElement = this.svgElement
|
this.axisElement = this.svgElement
|
||||||
@ -165,7 +165,7 @@ export default {
|
|||||||
this.xScale.range([PADDING, this.offsetWidth - PADDING * 2]);
|
this.xScale.range([PADDING, this.offsetWidth - PADDING * 2]);
|
||||||
},
|
},
|
||||||
setAxis() {
|
setAxis() {
|
||||||
this.xAxis = d3Axis.axisTop(this.xScale);
|
this.xAxis = axisTop(this.xScale);
|
||||||
this.xAxis.tickFormat(utcMultiTimeFormat);
|
this.xAxis.tickFormat(utcMultiTimeFormat);
|
||||||
|
|
||||||
if (this.width > 1800) {
|
if (this.width > 1800) {
|
||||||
|
Loading…
Reference in New Issue
Block a user