Compare commits
43 Commits
recursive-
...
tree-refac
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
15bef1c162 | ||
|
|
a2d21e3479 | ||
|
|
5693b153cb | ||
|
|
13e9541ad2 | ||
|
|
c0e3f6b577 | ||
|
|
43628ad9d6 | ||
|
|
67bea86bc8 | ||
|
|
4eb4cbfffc | ||
|
|
f763d1dea1 | ||
|
|
eda01abcbc | ||
|
|
694b8f4666 | ||
|
|
bbb271a678 | ||
|
|
fec1438806 | ||
|
|
28f19ec310 | ||
|
|
f934454c25 | ||
|
|
eb49ffae02 | ||
|
|
5751012872 | ||
|
|
aa041e04cf | ||
|
|
24e7ea143a | ||
|
|
79d5d9c4d0 | ||
|
|
b5bfdc4418 | ||
|
|
59730c60ec | ||
|
|
4a87a5d847 | ||
|
|
421c09ec2c | ||
|
|
0679b246b8 | ||
|
|
83f9c6c528 | ||
|
|
a5f3ba6259 | ||
|
|
a70facf0c8 | ||
|
|
447fe94325 | ||
|
|
8e2b666766 | ||
|
|
dcbfbdbb89 | ||
|
|
4c76bf34ab | ||
|
|
81b7a9d3e0 | ||
|
|
dc573c479c | ||
|
|
23303c910e | ||
|
|
3282934cf6 | ||
|
|
c157fab081 | ||
|
|
7c07b66cc9 | ||
|
|
7a906ccf5c | ||
|
|
ff7debfb81 | ||
|
|
92ba103f45 | ||
|
|
2c2d8d6b56 | ||
|
|
cfadb9f4fd |
@@ -20,8 +20,8 @@ jobs:
|
||||
paths:
|
||||
- node_modules
|
||||
- run:
|
||||
name: npm run test
|
||||
command: npm run test
|
||||
name: npm run test:coverage
|
||||
command: npm run test:coverage
|
||||
- run:
|
||||
name: npm run lint
|
||||
command: npm run lint
|
||||
|
||||
@@ -10,7 +10,8 @@ module.exports = {
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:vue/recommended"
|
||||
"plugin:vue/recommended",
|
||||
"plugin:you-dont-need-lodash-underscore/compatible"
|
||||
],
|
||||
"parser": "vue-eslint-parser",
|
||||
"parserOptions": {
|
||||
@@ -22,6 +23,9 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"you-dont-need-lodash-underscore/omit": "off",
|
||||
"you-dont-need-lodash-underscore/throttle": "off",
|
||||
"you-dont-need-lodash-underscore/flatten": "off",
|
||||
"no-bitwise": "error",
|
||||
"curly": "error",
|
||||
"eqeqeq": "error",
|
||||
|
||||
4
API.md
4
API.md
@@ -427,8 +427,8 @@ Each telemetry value description has an object defining hints. Keys in this thi
|
||||
|
||||
Known hints:
|
||||
|
||||
* `domain`: Indicates that the value represents the "input" of a datum. Values with a `domain` hint will be used for the x-axis of a plot, and tables will render columns for these values first.
|
||||
* `range`: Indicates that the value is the "output" of a datum. Values with a `range` hint will be used as the y-axis on a plot, and tables will render columns for these values after the `domain` values.
|
||||
* `domain`: Values with a `domain` hint will be used for the x-axis of a plot, and tables will render columns for these values first.
|
||||
* `range`: Values with a `range` hint will be used as the y-axis on a plot, and tables will render columns for these values after the `domain` values.
|
||||
* `image`: Indicates that the value may be interpreted as the URL to an image file, in which case appropriate views will be made available.
|
||||
|
||||
##### The Time Conductor and Telemetry
|
||||
|
||||
@@ -103,7 +103,7 @@ the name chosen could not be mistaken for a topic or master branch.
|
||||
### Merging
|
||||
|
||||
When development is complete on an issue, the first step toward merging it
|
||||
back into the master branch is to file a Pull Request. The contributions
|
||||
back into the master branch is to file a Pull Request (PR). The contributions
|
||||
should meet code, test, and commit message standards as described below,
|
||||
and the pull request should include a completed author checklist, also
|
||||
as described below. Pull requests may be assigned to specific team
|
||||
@@ -114,6 +114,15 @@ request. When the reviewer is satisfied, they should add a comment to
|
||||
the pull request containing the reviewer checklist (from below) and complete
|
||||
the merge back to the master branch.
|
||||
|
||||
Additionally:
|
||||
* Every pull request must link to the issue that it addresses. Eg. “Addresses #1234” or “Closes #1234”. This is the responsibility of the pull request’s __author__. If no issue exists, create one.
|
||||
* Every __author__ must include testing instructions. These instructions should identify the areas of code affected, and some minimal test steps. If addressing a bug, reproduction steps should be included, if they were not included in the original issue. If reproduction steps were included on the original issue, and are sufficient, refer to them.
|
||||
* A pull request that closes an issue should say so in the description. Including the text “Closes #1234” will cause the linked issue to be automatically closed when the pull request is merged. This is the responsibility of the pull request’s __author__.
|
||||
* When a pull request is merged, and the corresponding issue closed, the __reviewer__ must add the tag “unverified” to the original issue. This will indicate that although the issue is closed, it has not been tested yet.
|
||||
* Every PR must have two reviewers assigned, though only one approval is necessary for merge.
|
||||
* Changes to API require approval by a senior developer.
|
||||
* When creating a PR, it is the author's responsibility to apply any priority label from the issue to the PR as well. This helps with prioritization.
|
||||
|
||||
## Standards
|
||||
|
||||
Contributions to Open MCT are expected to meet the following standards.
|
||||
@@ -292,6 +301,7 @@ checklist).
|
||||
2. Unit tests included and/or updated with changes?
|
||||
3. Command line build passes?
|
||||
4. Changes have been smoke-tested?
|
||||
5. Testing instructions included?
|
||||
|
||||
### Reviewer Checklist
|
||||
|
||||
@@ -299,3 +309,4 @@ checklist).
|
||||
2. Appropriate unit tests included?
|
||||
3. Code style and in-line documentation are appropriate?
|
||||
4. Commit messages meet standards?
|
||||
5. Has associated issue been labelled `unverified`? (only applicable if this PR closes the issue)
|
||||
|
||||
@@ -50,7 +50,8 @@ define([
|
||||
values: [
|
||||
{
|
||||
key: "name",
|
||||
name: "Name"
|
||||
name: "Name",
|
||||
format: "string"
|
||||
},
|
||||
{
|
||||
key: "utc",
|
||||
@@ -99,7 +100,7 @@ define([
|
||||
};
|
||||
|
||||
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
||||
return _.extend(
|
||||
return Object.assign(
|
||||
{},
|
||||
domainObject.telemetry,
|
||||
METADATA_BY_TYPE[domainObject.type]
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<template>
|
||||
<div class="example">{{ msg }}</div>
|
||||
<div class="example">{{ msg }}</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data () {
|
||||
return {
|
||||
msg: 'Hello world!'
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello world!'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -24,16 +24,27 @@
|
||||
|
||||
const devMode = process.env.NODE_ENV !== 'production';
|
||||
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
|
||||
const coverageEnabled = process.env.COVERAGE === 'true';
|
||||
const reporters = ['progress', 'html'];
|
||||
|
||||
if (coverageEnabled) {
|
||||
reporters.push('coverage-istanbul');
|
||||
}
|
||||
|
||||
module.exports = (config) => {
|
||||
const webpackConfig = require('./webpack.config.js');
|
||||
delete webpackConfig.output;
|
||||
|
||||
if (!devMode) {
|
||||
if (!devMode || coverageEnabled) {
|
||||
webpackConfig.module.rules.push({
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules|example/,
|
||||
use: 'istanbul-instrumenter-loader'
|
||||
exclude: /node_modules|example|lib|dist/,
|
||||
use: {
|
||||
loader: 'istanbul-instrumenter-loader',
|
||||
options: {
|
||||
esModules: true
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -45,11 +56,7 @@ module.exports = (config) => {
|
||||
'src/**/*Spec.js'
|
||||
],
|
||||
port: 9876,
|
||||
reporters: [
|
||||
'progress',
|
||||
'coverage',
|
||||
'html'
|
||||
],
|
||||
reporters: reporters,
|
||||
browsers: browsers,
|
||||
customLaunchers: {
|
||||
ChromeDebugging: {
|
||||
@@ -61,27 +68,27 @@ module.exports = (config) => {
|
||||
colors: true,
|
||||
logLevel: config.LOG_INFO,
|
||||
autoWatch: true,
|
||||
coverageReporter: {
|
||||
dir: process.env.CIRCLE_ARTIFACTS ?
|
||||
process.env.CIRCLE_ARTIFACTS + '/coverage' :
|
||||
"dist/reports/coverage",
|
||||
check: {
|
||||
global: {
|
||||
lines: 80,
|
||||
excludes: ['src/plugins/plot/**/*.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
// HTML test reporting.
|
||||
htmlReporter: {
|
||||
outputDir: "dist/reports/tests",
|
||||
preserveDescribeNesting: true,
|
||||
foldAll: false
|
||||
},
|
||||
coverageIstanbulReporter: {
|
||||
fixWebpackSourcePaths: true,
|
||||
dir: process.env.CIRCLE_ARTIFACTS ?
|
||||
process.env.CIRCLE_ARTIFACTS + '/coverage' :
|
||||
"dist/reports/coverage",
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
thresholds: {
|
||||
global: {
|
||||
lines: 62
|
||||
}
|
||||
}
|
||||
},
|
||||
preprocessors: {
|
||||
// add webpack as preprocessor
|
||||
'platform/**/*Spec.js': [ 'webpack', 'sourcemap' ],
|
||||
'src/**/*Spec.js': [ 'webpack', 'sourcemap' ]
|
||||
'platform/**/*Spec.js': ['webpack', 'sourcemap'],
|
||||
'src/**/*Spec.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
|
||||
16
package.json
16
package.json
@@ -24,6 +24,7 @@
|
||||
"d3-time-format": "2.1.x",
|
||||
"eslint": "5.2.0",
|
||||
"eslint-plugin-vue": "^6.0.0",
|
||||
"eslint-plugin-you-dont-need-lodash-underscore": "^6.10.0",
|
||||
"eventemitter3": "^1.2.0",
|
||||
"exports-loader": "^0.7.0",
|
||||
"express": "^4.13.1",
|
||||
@@ -42,19 +43,20 @@
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-cli": "^1.0.1",
|
||||
"karma-coverage": "^1.1.2",
|
||||
"karma-coverage-istanbul-reporter": "^2.1.1",
|
||||
"karma-html-reporter": "^0.2.7",
|
||||
"karma-jasmine": "^1.1.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^3.0.0",
|
||||
"location-bar": "^3.0.1",
|
||||
"lodash": "^3.10.1",
|
||||
"lodash": "^4.17.12",
|
||||
"markdown-toc": "^0.11.7",
|
||||
"marked": "^0.3.5",
|
||||
"mini-css-extract-plugin": "^0.4.1",
|
||||
"minimist": "^1.1.1",
|
||||
"moment": "^2.11.1",
|
||||
"moment": "2.25.3",
|
||||
"moment-duration-format": "^2.2.2",
|
||||
"moment-timezone": "^0.5.21",
|
||||
"moment-timezone": "0.5.28",
|
||||
"node-bourbon": "^4.2.3",
|
||||
"node-sass": "^4.9.2",
|
||||
"painterro": "^0.2.65",
|
||||
@@ -75,14 +77,16 @@
|
||||
"zepto": "^1.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"clean": "rm -rf ./dist",
|
||||
"start": "node app.js",
|
||||
"lint": "eslint platform example src/**/*.{js,vue} openmct.js",
|
||||
"lint:fix": "eslint platform example src/**/*.{js,vue} openmct.js --fix",
|
||||
"lint": "eslint platform example src --ext .js,.vue openmct.js",
|
||||
"lint:fix": "eslint platform example src --ext .js,.vue openmct.js --fix",
|
||||
"build:prod": "cross-env NODE_ENV=production webpack",
|
||||
"build:dev": "webpack",
|
||||
"build:watch": "webpack --watch",
|
||||
"test": "karma start --single-run",
|
||||
"test-debug": "cross-env NODE_ENV=debug karma start --no-single-run",
|
||||
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
|
||||
"test:coverage": "./scripts/test-coverage.sh",
|
||||
"test:watch": "karma start --no-single-run",
|
||||
"verify": "concurrently 'npm:test' 'npm:lint'",
|
||||
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
['../../../../../src/api/objects/object-utils'],
|
||||
['objectUtils'],
|
||||
function (objectUtils) {
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
* @namespace platform/containment
|
||||
*/
|
||||
define(
|
||||
['../../../src/api/objects/object-utils'],
|
||||
['objectUtils'],
|
||||
function (objectUtils) {
|
||||
|
||||
function PersistableCompositionPolicy(openmct) {
|
||||
|
||||
@@ -81,7 +81,7 @@ define(
|
||||
baseContext = context || {};
|
||||
}
|
||||
|
||||
var actionContext = _.extend({}, baseContext);
|
||||
var actionContext = Object.assign({}, baseContext);
|
||||
actionContext.domainObject = this.domainObject;
|
||||
|
||||
return this.actionService.getActions(actionContext);
|
||||
|
||||
@@ -121,7 +121,7 @@ define(['lodash'], function (_) {
|
||||
*/
|
||||
ExportAsJSONAction.prototype.rewriteLink = function (child, parent) {
|
||||
this.externalIdentifiers.push(this.getId(child));
|
||||
var index = _.findIndex(parent.composition, function (id) {
|
||||
var index = parent.composition.findIndex(id => {
|
||||
return _.isEqual(child.identifier, id);
|
||||
});
|
||||
var copyOfChild = this.copyObject(child);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
define(['zepto', '../../../../src/api/objects/object-utils.js'], function ($, objectUtils) {
|
||||
define(['zepto', 'objectUtils'], function ($, objectUtils) {
|
||||
|
||||
/**
|
||||
* The ImportAsJSONAction is available from context menus and allows a user
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
* Module defining GenericSearchProvider. Created by shale on 07/16/2015.
|
||||
*/
|
||||
define([
|
||||
'../../../../src/api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
], function (
|
||||
objectUtils,
|
||||
@@ -191,7 +191,7 @@ define([
|
||||
}
|
||||
|
||||
var domainObject = objectUtils.toNewFormat(model, id);
|
||||
var composition = _.find(this.openmct.composition.registry, function (p) {
|
||||
var composition = this.openmct.composition.registry.find(p => {
|
||||
return p.appliesTo(domainObject);
|
||||
});
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
*/
|
||||
define(
|
||||
[
|
||||
'../../../src/api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
],
|
||||
function (
|
||||
@@ -235,7 +235,7 @@ define(
|
||||
var defaultRange = metadata.valuesForHints(['range'])[0];
|
||||
defaultRange = defaultRange ? defaultRange.key : undefined;
|
||||
|
||||
var sourceMap = _.indexBy(metadata.values(), 'key');
|
||||
var sourceMap = _.keyBy(metadata.values(), 'key');
|
||||
|
||||
var isLegacyProvider = telemetryAPI.findRequestProvider(domainObject) ===
|
||||
telemetryAPI.legacyProvider;
|
||||
@@ -300,7 +300,7 @@ define(
|
||||
var defaultRange = metadata.valuesForHints(['range'])[0];
|
||||
defaultRange = defaultRange ? defaultRange.key : undefined;
|
||||
|
||||
var sourceMap = _.indexBy(metadata.values(), 'key');
|
||||
var sourceMap = _.keyBy(metadata.values(), 'key');
|
||||
|
||||
var isLegacyProvider = telemetryAPI.findSubscriptionProvider(domainObject) ===
|
||||
telemetryAPI.legacyProvider;
|
||||
|
||||
2
scripts/test-coverage.sh
Executable file
2
scripts/test-coverage.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
export NODE_OPTIONS=--max_old_space_size=4096
|
||||
cross-env COVERAGE=true karma start --single-run
|
||||
41
src/MCT.js
41
src/MCT.js
@@ -28,7 +28,7 @@ define([
|
||||
'./api/api',
|
||||
'./api/overlays/OverlayAPI',
|
||||
'./selection/Selection',
|
||||
'./api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'./plugins/plugins',
|
||||
'./adapter/indicators/legacy-indicators-plugin',
|
||||
'./plugins/buildInfo/plugin',
|
||||
@@ -249,7 +249,7 @@ define([
|
||||
this.legacyRegistry = new BundleRegistry();
|
||||
installDefaultBundles(this.legacyRegistry);
|
||||
|
||||
// Plugin's that are installed by default
|
||||
// Plugins that are installed by default
|
||||
|
||||
this.install(this.plugins.Plot());
|
||||
this.install(this.plugins.TelemetryTable());
|
||||
@@ -350,17 +350,13 @@ define([
|
||||
* @param {HTMLElement} [domElement] the DOM element in which to run
|
||||
* MCT; if undefined, MCT will be run in the body of the document
|
||||
*/
|
||||
MCT.prototype.start = function (domElement) {
|
||||
MCT.prototype.start = function (domElement = document.body, isHeadlessMode = false) {
|
||||
if (!this.plugins.DisplayLayout._installed) {
|
||||
this.install(this.plugins.DisplayLayout({
|
||||
showAsView: ['summary-widget']
|
||||
}));
|
||||
}
|
||||
|
||||
if (!domElement) {
|
||||
domElement = document.body;
|
||||
}
|
||||
|
||||
this.element = domElement;
|
||||
|
||||
this.legacyExtension('runs', {
|
||||
@@ -400,24 +396,31 @@ define([
|
||||
// something has depended upon objectService. Cool, right?
|
||||
this.$injector.get('objectService');
|
||||
|
||||
var appLayout = new Vue({
|
||||
components: {
|
||||
'Layout': Layout.default
|
||||
},
|
||||
provide: {
|
||||
openmct: this
|
||||
},
|
||||
template: '<Layout ref="layout"></Layout>'
|
||||
});
|
||||
domElement.appendChild(appLayout.$mount().$el);
|
||||
if (!isHeadlessMode) {
|
||||
var appLayout = new Vue({
|
||||
components: {
|
||||
'Layout': Layout.default
|
||||
},
|
||||
provide: {
|
||||
openmct: this
|
||||
},
|
||||
template: '<Layout ref="layout"></Layout>'
|
||||
});
|
||||
domElement.appendChild(appLayout.$mount().$el);
|
||||
|
||||
this.layout = appLayout.$refs.layout;
|
||||
Browse(this);
|
||||
this.layout = appLayout.$refs.layout;
|
||||
Browse(this);
|
||||
}
|
||||
this.router.start();
|
||||
this.emit('start');
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
MCT.prototype.startHeadless = function () {
|
||||
let unreachableNode = document.createElement('div');
|
||||
return this.start(unreachableNode, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a plugin in MCT.
|
||||
*
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'./MCT',
|
||||
'./plugins/plugins',
|
||||
'legacyRegistry'
|
||||
], function (MCT, plugins, legacyRegistry) {
|
||||
xdescribe("MCT", function () {
|
||||
'legacyRegistry',
|
||||
'testUtils'
|
||||
], function (plugins, legacyRegistry, testUtils) {
|
||||
describe("MCT", function () {
|
||||
var openmct;
|
||||
var mockPlugin;
|
||||
var mockPlugin2;
|
||||
@@ -38,7 +38,7 @@ define([
|
||||
mockListener = jasmine.createSpy('listener');
|
||||
oldBundles = legacyRegistry.list();
|
||||
|
||||
openmct = new MCT();
|
||||
openmct = testUtils.createOpenMct();
|
||||
|
||||
openmct.install(mockPlugin);
|
||||
openmct.install(mockPlugin2);
|
||||
@@ -63,8 +63,11 @@ define([
|
||||
});
|
||||
|
||||
describe("start", function () {
|
||||
beforeEach(function () {
|
||||
openmct.start();
|
||||
let appHolder;
|
||||
beforeEach(function (done) {
|
||||
appHolder = document.createElement("div");
|
||||
openmct.on('start', done);
|
||||
openmct.start(appHolder);
|
||||
});
|
||||
|
||||
it("calls plugins for configuration", function () {
|
||||
@@ -75,25 +78,51 @@ define([
|
||||
it("emits a start event", function () {
|
||||
expect(mockListener).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Renders the application into the provided container element", function () {
|
||||
let openMctShellElements = appHolder.querySelectorAll('div.l-shell');
|
||||
expect(openMctShellElements.length).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe("startHeadless", function () {
|
||||
beforeEach(function (done) {
|
||||
openmct.on('start', done);
|
||||
openmct.startHeadless();
|
||||
});
|
||||
|
||||
it("calls plugins for configuration", function () {
|
||||
expect(mockPlugin).toHaveBeenCalledWith(openmct);
|
||||
expect(mockPlugin2).toHaveBeenCalledWith(openmct);
|
||||
});
|
||||
|
||||
it("emits a start event", function () {
|
||||
expect(mockListener).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Does not render Open MCT", function () {
|
||||
let openMctShellElements = document.body.querySelectorAll('div.l-shell');
|
||||
expect(openMctShellElements.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("setAssetPath", function () {
|
||||
var testAssetPath;
|
||||
|
||||
beforeEach(function () {
|
||||
testAssetPath = "some/path";
|
||||
openmct.legacyExtension = jasmine.createSpy('legacyExtension');
|
||||
openmct.setAssetPath(testAssetPath);
|
||||
});
|
||||
|
||||
it("internally configures the path for assets", function () {
|
||||
expect(openmct.legacyExtension).toHaveBeenCalledWith(
|
||||
'constants',
|
||||
{
|
||||
key: "ASSETS_PATH",
|
||||
value: testAssetPath
|
||||
}
|
||||
);
|
||||
it("configures the path for assets", function () {
|
||||
testAssetPath = "some/path/";
|
||||
openmct.setAssetPath(testAssetPath);
|
||||
expect(openmct.getAssetPath()).toBe(testAssetPath);
|
||||
});
|
||||
|
||||
it("adds a trailing /", function () {
|
||||
testAssetPath = "some/path";
|
||||
openmct.setAssetPath(testAssetPath);
|
||||
expect(openmct.getAssetPath()).toBe(testAssetPath + "/");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (objectUtils) {
|
||||
function ActionDialogDecorator(mct, actionService) {
|
||||
this.mct = mct;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(['../../api/objects/object-utils'], function (objectUtils) {
|
||||
define(['objectUtils'], function (objectUtils) {
|
||||
function AdapterCapability(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
* Module defining AlternateCompositionCapability. Created by vwoeltje on 11/7/14.
|
||||
*/
|
||||
define([
|
||||
'../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'../../../platform/core/src/capabilities/ContextualDomainObject'
|
||||
], function (objectUtils, ContextualDomainObject) {
|
||||
function AlternateCompositionCapability($injector, domainObject) {
|
||||
|
||||
@@ -31,6 +31,7 @@ define([
|
||||
var capability = viewConstructor(domainObject);
|
||||
var oldInvoke = capability.invoke.bind(capability);
|
||||
|
||||
/* eslint-disable you-dont-need-lodash-underscore/map */
|
||||
capability.invoke = function () {
|
||||
var availableViews = oldInvoke();
|
||||
var newDomainObject = capability
|
||||
@@ -52,6 +53,8 @@ define([
|
||||
.map('view')
|
||||
.value();
|
||||
};
|
||||
/* eslint-enable you-dont-need-lodash-underscore/map */
|
||||
|
||||
return capability;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
define([
|
||||
'../capabilities/AlternateCompositionCapability',
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
AlternateCompositionCapability,
|
||||
objectUtils
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
utils
|
||||
) {
|
||||
|
||||
@@ -78,7 +78,7 @@ define([
|
||||
};
|
||||
|
||||
TimeSettingsURLHandler.prototype.parseQueryParams = function () {
|
||||
var searchParams = _.pick(this.$location.search(), _.values(SEARCH));
|
||||
var searchParams = _.pick(this.$location.search(), Object.values(SEARCH));
|
||||
var parsedParams = {
|
||||
clock: searchParams[SEARCH.MODE],
|
||||
timeSystem: searchParams[SEARCH.TIME_SYSTEM]
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
utils
|
||||
) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
objectUtils
|
||||
) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define([
|
||||
'./LegacyViewProvider',
|
||||
'./TypeInspectorViewProvider',
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
LegacyViewProvider,
|
||||
TypeInspectorViewProvider,
|
||||
|
||||
@@ -70,7 +70,7 @@ define([
|
||||
* @memberof module:openmct.CompositionAPI#
|
||||
*/
|
||||
CompositionAPI.prototype.get = function (domainObject) {
|
||||
var provider = _.find(this.registry, function (p) {
|
||||
var provider = this.registry.find(p => {
|
||||
return p.appliesTo(domainObject);
|
||||
});
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ define([
|
||||
throw new Error('Event not supported by composition: ' + event);
|
||||
}
|
||||
|
||||
var index = _.findIndex(this.listeners[event], function (l) {
|
||||
var index = this.listeners[event].findIndex(l => {
|
||||
return l.callback === callback && l.context === context;
|
||||
});
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
define([
|
||||
'lodash',
|
||||
'../objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
_,
|
||||
objectUtils
|
||||
@@ -143,7 +143,7 @@ define([
|
||||
var keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||
var objectListeners = this.listeningTo[keyString];
|
||||
|
||||
var index = _.findIndex(objectListeners[event], function (l) {
|
||||
var index = objectListeners[event].findIndex(l => {
|
||||
return l.callback === callback && l.context === context;
|
||||
});
|
||||
|
||||
@@ -196,8 +196,8 @@ define([
|
||||
* @private
|
||||
*/
|
||||
DefaultCompositionProvider.prototype.includes = function (parent, childId) {
|
||||
return parent.composition.findIndex(composee =>
|
||||
this.publicAPI.objects.areIdsEqual(composee, childId)) !== -1;
|
||||
return parent.composition.some(composee =>
|
||||
this.publicAPI.objects.areIdsEqual(composee, childId));
|
||||
};
|
||||
|
||||
DefaultCompositionProvider.prototype.reorder = function (domainObject, oldIndex, newIndex) {
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'./object-utils.js',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
], function (
|
||||
utils,
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
define([
|
||||
'lodash',
|
||||
'./object-utils',
|
||||
'objectUtils',
|
||||
'./MutableObject',
|
||||
'./RootRegistry',
|
||||
'./RootObjectProvider',
|
||||
|
||||
@@ -43,7 +43,7 @@ define([
|
||||
}
|
||||
|
||||
RootRegistry.prototype.addRoot = function (key) {
|
||||
if (isKey(key) || (_.isArray(key) && _.every(key, isKey))) {
|
||||
if (isKey(key) || (Array.isArray(key) && key.every(isKey))) {
|
||||
this.providers.push(function () {
|
||||
return key;
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define([
|
||||
'../object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
objectUtils
|
||||
) {
|
||||
|
||||
@@ -85,9 +85,9 @@ define([
|
||||
value: +e.value
|
||||
};
|
||||
}), 'e.value');
|
||||
valueMetadata.values = _.pluck(valueMetadata.enumerations, 'value');
|
||||
valueMetadata.max = _.max(valueMetadata.values);
|
||||
valueMetadata.min = _.min(valueMetadata.values);
|
||||
valueMetadata.values = valueMetadata.enumerations.map(e => e.value);
|
||||
valueMetadata.max = Math.max(valueMetadata.values);
|
||||
valueMetadata.min = Math.min(valueMetadata.values);
|
||||
}
|
||||
|
||||
valueMetadatas.push(valueMetadata);
|
||||
@@ -103,7 +103,7 @@ define([
|
||||
var metadata = domainObject.telemetry || {};
|
||||
if (this.typeHasTelemetry(domainObject)) {
|
||||
var typeMetadata = this.typeService.getType(domainObject.type).typeDef.telemetry;
|
||||
_.extend(metadata, typeMetadata);
|
||||
Object.assign(metadata, typeMetadata);
|
||||
if (!metadata.values) {
|
||||
metadata.values = valueMetadatasFromOldFormat(metadata);
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ define([
|
||||
'./TelemetryMetadataManager',
|
||||
'./TelemetryValueFormatter',
|
||||
'./DefaultMetadataProvider',
|
||||
'../objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
], function (
|
||||
TelemetryMetadataManager,
|
||||
@@ -370,7 +370,7 @@ define([
|
||||
TelemetryAPI.prototype.commonValuesForHints = function (metadatas, hints) {
|
||||
var options = metadatas.map(function (metadata) {
|
||||
var values = metadata.valuesForHints(hints);
|
||||
return _.indexBy(values, 'key');
|
||||
return _.keyBy(values, 'key');
|
||||
}).reduce(function (a, b) {
|
||||
var results = {};
|
||||
Object.keys(a).forEach(function (key) {
|
||||
@@ -383,7 +383,7 @@ define([
|
||||
var sortKeys = hints.map(function (h) {
|
||||
return 'hints.' + h;
|
||||
});
|
||||
return _.sortByAll(options, sortKeys);
|
||||
return _.sortBy(options, sortKeys);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,13 +57,13 @@ define([
|
||||
|
||||
if (valueMetadata.format === 'enum') {
|
||||
if (!valueMetadata.values) {
|
||||
valueMetadata.values = _.pluck(valueMetadata.enumerations, 'value');
|
||||
valueMetadata.values = valueMetadata.enumerations.map(e => e.value);
|
||||
}
|
||||
if (!valueMetadata.hasOwnProperty('max')) {
|
||||
valueMetadata.max = _.max(valueMetadata.values) + 1;
|
||||
valueMetadata.max = Math.max(valueMetadata.values) + 1;
|
||||
}
|
||||
if (!valueMetadata.hasOwnProperty('min')) {
|
||||
valueMetadata.min = _.min(valueMetadata.values) - 1;
|
||||
valueMetadata.min = Math.min(valueMetadata.values) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ define([
|
||||
return metadata.hints[hint];
|
||||
}
|
||||
});
|
||||
return _.sortByAll(matchingMetadata, ...iteratees);
|
||||
return _.sortBy(matchingMetadata, ...iteratees);
|
||||
};
|
||||
|
||||
TelemetryMetadataManager.prototype.getFilterableValues = function () {
|
||||
|
||||
@@ -75,7 +75,7 @@ export default {
|
||||
this.items.push(item);
|
||||
},
|
||||
removeItem(identifier) {
|
||||
let index = _.findIndex(this.items, (item) => this.openmct.objects.makeKeyString(identifier) === item.key);
|
||||
let index = this.items.findIndex(item => this.openmct.objects.makeKeyString(identifier) === item.key);
|
||||
|
||||
this.items.splice(index, 1);
|
||||
},
|
||||
|
||||
@@ -102,7 +102,7 @@ export default {
|
||||
this.compositions.push({composition, addCallback, removeCallback});
|
||||
},
|
||||
removePrimary(identifier) {
|
||||
let index = _.findIndex(this.primaryTelemetryObjects, (primary) => this.openmct.objects.makeKeyString(identifier) === primary.key),
|
||||
let index = this.primaryTelemetryObjects.findIndex(primary => this.openmct.objects.makeKeyString(identifier) === primary.key),
|
||||
primary = this.primaryTelemetryObjects[index];
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
|
||||
@@ -130,7 +130,7 @@ export default {
|
||||
removeSecondary(primary) {
|
||||
return (identifier) => {
|
||||
let array = this.secondaryTelemetryObjects[primary.key],
|
||||
index = _.findIndex(array, (secondary) => this.openmct.objects.makeKeyString(identifier) === secondary.key);
|
||||
index = array.findIndex(secondary => this.openmct.objects.makeKeyString(identifier) === secondary.key);
|
||||
|
||||
array.splice(index, 1);
|
||||
|
||||
|
||||
@@ -70,15 +70,18 @@ export default class ConditionClass extends EventEmitter {
|
||||
return;
|
||||
}
|
||||
|
||||
this.criteria.forEach(criterion => {
|
||||
if (this.isAnyOrAllTelemetry(criterion)) {
|
||||
criterion.getResult(datum, this.conditionManager.telemetryObjects);
|
||||
} else {
|
||||
criterion.getResult(datum);
|
||||
}
|
||||
});
|
||||
if (this.isTelemetryUsed(datum.id)) {
|
||||
|
||||
this.result = evaluateResults(this.criteria.map(criterion => criterion.result), this.trigger);
|
||||
this.criteria.forEach(criterion => {
|
||||
if (this.isAnyOrAllTelemetry(criterion)) {
|
||||
criterion.getResult(datum, this.conditionManager.telemetryObjects);
|
||||
} else {
|
||||
criterion.getResult(datum);
|
||||
}
|
||||
});
|
||||
|
||||
this.result = evaluateResults(this.criteria.map(criterion => criterion.result), this.trigger);
|
||||
}
|
||||
}
|
||||
|
||||
isAnyOrAllTelemetry(criterion) {
|
||||
|
||||
@@ -47,17 +47,24 @@ describe("The condition", function () {
|
||||
name: "Test Object",
|
||||
telemetry: {
|
||||
values: [{
|
||||
key: "some-key",
|
||||
name: "Some attribute",
|
||||
key: "value",
|
||||
name: "Value",
|
||||
hints: {
|
||||
range: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "utc",
|
||||
name: "Time",
|
||||
format: "utc",
|
||||
hints: {
|
||||
domain: 1
|
||||
}
|
||||
}, {
|
||||
key: "some-other-key",
|
||||
name: "Another attribute",
|
||||
hints: {
|
||||
range: 1
|
||||
}
|
||||
key: "testSource",
|
||||
source: "value",
|
||||
name: "Test",
|
||||
format: "string"
|
||||
}]
|
||||
}
|
||||
};
|
||||
@@ -136,4 +143,38 @@ describe("The condition", function () {
|
||||
expect(result).toBeTrue();
|
||||
expect(conditionObj.criteria.length).toEqual(0);
|
||||
});
|
||||
|
||||
it("gets the result of a condition when new telemetry data is received", function () {
|
||||
conditionObj.getResult({
|
||||
value: '0',
|
||||
utc: 'Hi',
|
||||
id: testTelemetryObject.identifier.key
|
||||
});
|
||||
expect(conditionObj.result).toBeTrue();
|
||||
});
|
||||
|
||||
it("gets the result of a condition when new telemetry data is received", function () {
|
||||
conditionObj.getResult({
|
||||
value: '1',
|
||||
utc: 'Hi',
|
||||
id: testTelemetryObject.identifier.key
|
||||
});
|
||||
expect(conditionObj.result).toBeFalse();
|
||||
});
|
||||
|
||||
it("keeps the old result new telemetry data is not used by it", function () {
|
||||
conditionObj.getResult({
|
||||
value: '0',
|
||||
utc: 'Hi',
|
||||
id: testTelemetryObject.identifier.key
|
||||
});
|
||||
expect(conditionObj.result).toBeTrue();
|
||||
|
||||
conditionObj.getResult({
|
||||
value: '1',
|
||||
utc: 'Hi',
|
||||
id: '1234'
|
||||
});
|
||||
expect(conditionObj.result).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -23,10 +23,13 @@
|
||||
import EventEmitter from 'EventEmitter';
|
||||
|
||||
export default class StyleRuleManager extends EventEmitter {
|
||||
constructor(styleConfiguration, openmct, callback) {
|
||||
constructor(styleConfiguration, openmct, callback, suppressSubscriptionOnEdit) {
|
||||
super();
|
||||
this.openmct = openmct;
|
||||
this.callback = callback;
|
||||
if (suppressSubscriptionOnEdit) {
|
||||
this.openmct.editor.on('isEditing', this.toggleSubscription.bind(this));
|
||||
}
|
||||
if (styleConfiguration) {
|
||||
this.initialize(styleConfiguration);
|
||||
if (styleConfiguration.conditionSetIdentifier) {
|
||||
@@ -37,9 +40,25 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
toggleSubscription(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
if (this.isEditing) {
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
}
|
||||
if (this.conditionSetIdentifier) {
|
||||
this.applySelectedConditionStyle();
|
||||
}
|
||||
} else if (this.conditionSetIdentifier) {
|
||||
this.subscribeToConditionSet();
|
||||
}
|
||||
}
|
||||
|
||||
initialize(styleConfiguration) {
|
||||
this.conditionSetIdentifier = styleConfiguration.conditionSetIdentifier;
|
||||
this.staticStyle = styleConfiguration.staticStyle;
|
||||
this.selectedConditionId = styleConfiguration.selectedConditionId;
|
||||
this.defaultConditionId = styleConfiguration.defaultConditionId;
|
||||
this.updateConditionStylesMap(styleConfiguration.styles || []);
|
||||
}
|
||||
|
||||
@@ -54,7 +73,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
this.handleConditionSetResultUpdated(output[0]);
|
||||
}
|
||||
});
|
||||
this.stopProvidingTelemetry = this.openmct.telemetry.subscribe(conditionSetDomainObject, output => this.handleConditionSetResultUpdated(output));
|
||||
this.stopProvidingTelemetry = this.openmct.telemetry.subscribe(conditionSetDomainObject, this.handleConditionSetResultUpdated.bind(this));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -66,9 +85,13 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
let isNewConditionSet = !this.conditionSetIdentifier ||
|
||||
!this.openmct.objects.areIdsEqual(this.conditionSetIdentifier, styleConfiguration.conditionSetIdentifier);
|
||||
this.initialize(styleConfiguration);
|
||||
//Only resubscribe if the conditionSet has changed.
|
||||
if (isNewConditionSet) {
|
||||
this.subscribeToConditionSet();
|
||||
if (this.isEditing) {
|
||||
this.applySelectedConditionStyle();
|
||||
} else {
|
||||
//Only resubscribe if the conditionSet has changed.
|
||||
if (isNewConditionSet) {
|
||||
this.subscribeToConditionSet();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +126,16 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
applySelectedConditionStyle() {
|
||||
const conditionId = this.selectedConditionId || this.defaultConditionId;
|
||||
if (!conditionId) {
|
||||
this.applyStaticStyle();
|
||||
} else if (this.conditionalStyleMap[conditionId]) {
|
||||
this.currentStyle = this.conditionalStyleMap[conditionId];
|
||||
this.updateDomainObjectStyle();
|
||||
}
|
||||
}
|
||||
|
||||
applyStaticStyle() {
|
||||
if (this.staticStyle) {
|
||||
this.currentStyle = this.staticStyle.style;
|
||||
@@ -123,6 +156,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
}
|
||||
delete this.stopProvidingTelemetry;
|
||||
this.conditionSetIdentifier = undefined;
|
||||
this.isEditing = undefined;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
>
|
||||
<div class="c-condition-h__drop-target"></div>
|
||||
<div v-if="isEditing"
|
||||
:class="{'is-current': condition.id === currentConditionId}"
|
||||
class="c-condition c-condition--edit"
|
||||
>
|
||||
<!-- Edit view -->
|
||||
@@ -167,6 +168,7 @@
|
||||
</div>
|
||||
<div v-else
|
||||
class="c-condition c-condition--browse"
|
||||
:class="{'is-current': condition.id === currentConditionId}"
|
||||
>
|
||||
<!-- Browse view -->
|
||||
<div class="c-condition__header">
|
||||
@@ -199,6 +201,10 @@ export default {
|
||||
ConditionDescription
|
||||
},
|
||||
props: {
|
||||
currentConditionId: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
condition: {
|
||||
type: Object,
|
||||
required: true
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
<Condition v-for="(condition, index) in conditionCollection"
|
||||
:key="condition.id"
|
||||
:condition="condition"
|
||||
:current-condition-id="currentConditionId"
|
||||
:condition-index="index"
|
||||
:telemetry="telemetryObjs"
|
||||
:is-editing="isEditing"
|
||||
@@ -107,7 +108,8 @@ export default {
|
||||
moveIndex: undefined,
|
||||
isDragging: false,
|
||||
defaultOutput: undefined,
|
||||
dragCounter: 0
|
||||
dragCounter: 0,
|
||||
currentConditionId: ''
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
@@ -145,6 +147,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
handleConditionSetResultUpdated(data) {
|
||||
this.currentConditionId = data.conditionId;
|
||||
this.$emit('conditionSetResultUpdated', data)
|
||||
},
|
||||
observeForChanges() {
|
||||
@@ -197,7 +200,7 @@ export default {
|
||||
this.$emit('telemetryUpdated', this.telemetryObjs);
|
||||
},
|
||||
removeTelemetryObject(identifier) {
|
||||
let index = _.findIndex(this.telemetryObjs, (obj) => {
|
||||
let index = this.telemetryObjs.findIndex(obj => {
|
||||
let objId = this.openmct.objects.makeKeyString(obj.identifier);
|
||||
let id = this.openmct.objects.makeKeyString(identifier);
|
||||
return objId === id;
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
}
|
||||
|
||||
.c-condition {
|
||||
border: 1px solid transparent;
|
||||
flex-direction: column;
|
||||
min-width: 400px;
|
||||
|
||||
@@ -234,6 +235,12 @@
|
||||
&__summary {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&.is-current {
|
||||
$c: $colorBodyFg;
|
||||
border-color: rgba($c, 0.2);
|
||||
background: rgba($c, 0.2);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************** CONDITION DEFINITION, EDITING */
|
||||
|
||||
@@ -79,6 +79,8 @@
|
||||
<div v-for="(conditionStyle, index) in conditionalStyles"
|
||||
:key="index"
|
||||
class="c-inspect-styles__condition"
|
||||
:class="{'is-current': conditionStyle.conditionId === selectedConditionId}"
|
||||
@click="applySelectedConditionStyle(conditionStyle.conditionId)"
|
||||
>
|
||||
<condition-error :show-label="true"
|
||||
:condition="getCondition(conditionStyle.conditionId)"
|
||||
@@ -106,6 +108,7 @@ import ConditionError from "@/plugins/condition/components/ConditionError.vue";
|
||||
import Vue from 'vue';
|
||||
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||
import {getApplicableStylesForItem} from "@/plugins/condition/utils/styleUtils";
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
export default {
|
||||
name: 'ConditionalStylesView',
|
||||
@@ -126,7 +129,8 @@ export default {
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
conditions: undefined,
|
||||
conditionsLoaded: false,
|
||||
navigateToPath: ''
|
||||
navigateToPath: '',
|
||||
selectedConditionId: ''
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
@@ -191,6 +195,9 @@ export default {
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
}
|
||||
},
|
||||
initialize(conditionSetDomainObject) {
|
||||
//If there are new conditions in the conditionSet we need to set those styles to default
|
||||
@@ -200,6 +207,13 @@ export default {
|
||||
},
|
||||
setEditState(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
if (this.isEditing) {
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
}
|
||||
} else {
|
||||
this.subscribeToConditionSet();
|
||||
}
|
||||
},
|
||||
addConditionSet() {
|
||||
let conditionSetDomainObject;
|
||||
@@ -270,33 +284,44 @@ export default {
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (this.itemId) {
|
||||
domainObjectStyles[this.itemId].conditionSetIdentifier = undefined;
|
||||
domainObjectStyles[this.itemId].selectedConditionId = undefined;
|
||||
domainObjectStyles[this.itemId].defaultConditionId = undefined;
|
||||
delete domainObjectStyles[this.itemId].conditionSetIdentifier;
|
||||
domainObjectStyles[this.itemId].styles = undefined;
|
||||
delete domainObjectStyles[this.itemId].styles;
|
||||
if (_.isEmpty(domainObjectStyles[this.itemId])) {
|
||||
if (isEmpty(domainObjectStyles[this.itemId])) {
|
||||
delete domainObjectStyles[this.itemId];
|
||||
}
|
||||
} else {
|
||||
domainObjectStyles.conditionSetIdentifier = undefined;
|
||||
domainObjectStyles.selectedConditionId = undefined;
|
||||
domainObjectStyles.defaultConditionId = undefined;
|
||||
delete domainObjectStyles.conditionSetIdentifier;
|
||||
domainObjectStyles.styles = undefined;
|
||||
delete domainObjectStyles.styles;
|
||||
}
|
||||
if (_.isEmpty(domainObjectStyles)) {
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
|
||||
this.persist(domainObjectStyles);
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
}
|
||||
},
|
||||
updateDomainObjectItemStyles(newItems) {
|
||||
//check that all items that have been styles still exist. Otherwise delete those styles
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let itemsToRemove = [];
|
||||
let keys = Object.keys(domainObjectStyles);
|
||||
//TODO: Need an easier way to find which properties are itemIds
|
||||
keys.forEach((key) => {
|
||||
if ((key !== 'styles') &&
|
||||
const keyIsItemId = (key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'conditionSetIdentifier')) {
|
||||
(key !== 'defaultConditionId') &&
|
||||
(key !== 'selectedConditionId') &&
|
||||
(key !== 'conditionSetIdentifier');
|
||||
if (keyIsItemId) {
|
||||
if (!(newItems.find(item => item.id === key))) {
|
||||
itemsToRemove.push(key);
|
||||
}
|
||||
@@ -313,7 +338,7 @@ export default {
|
||||
delete domainObjectStyles[this.itemId];
|
||||
}
|
||||
});
|
||||
if (_.isEmpty(domainObjectStyles)) {
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
this.persist(domainObjectStyles);
|
||||
@@ -324,6 +349,9 @@ export default {
|
||||
}
|
||||
let conditionalStyles = [];
|
||||
this.conditionSetDomainObject.configuration.conditionCollection.forEach((conditionConfiguration, index) => {
|
||||
if (conditionConfiguration.isDefault) {
|
||||
this.selectedConditionId = conditionConfiguration.id;
|
||||
}
|
||||
this.conditions[conditionConfiguration.id] = conditionConfiguration;
|
||||
let foundStyle = this.findStyleByConditionId(conditionConfiguration.id);
|
||||
if (foundStyle) {
|
||||
@@ -339,7 +367,27 @@ export default {
|
||||
//we're doing this so that we remove styles for any conditions that have been removed from the condition set
|
||||
this.conditionalStyles = conditionalStyles;
|
||||
this.conditionsLoaded = true;
|
||||
this.persist(this.getDomainObjectConditionalStyle());
|
||||
this.persist(this.getDomainObjectConditionalStyle(this.selectedConditionId));
|
||||
if (!this.isEditing) {
|
||||
this.subscribeToConditionSet();
|
||||
}
|
||||
},
|
||||
subscribeToConditionSet() {
|
||||
if (this.stopProvidingTelemetry) {
|
||||
this.stopProvidingTelemetry();
|
||||
}
|
||||
if (this.conditionSetDomainObject) {
|
||||
this.openmct.telemetry.request(this.conditionSetDomainObject)
|
||||
.then(output => {
|
||||
if (output && output.length) {
|
||||
this.handleConditionSetResultUpdated(output[0]);
|
||||
}
|
||||
});
|
||||
this.stopProvidingTelemetry = this.openmct.telemetry.subscribe(this.conditionSetDomainObject, this.handleConditionSetResultUpdated.bind(this));
|
||||
}
|
||||
},
|
||||
handleConditionSetResultUpdated(resultData) {
|
||||
this.selectedConditionId = resultData ? resultData.conditionId : '';
|
||||
},
|
||||
initializeStaticStyle(objectStyles) {
|
||||
let staticStyle = objectStyles && objectStyles.staticStyle;
|
||||
@@ -364,14 +412,19 @@ export default {
|
||||
let found = this.findStyleByConditionId(conditionStyle.conditionId);
|
||||
if (found) {
|
||||
found.style = conditionStyle.style;
|
||||
this.selectedConditionId = found.conditionId;
|
||||
this.persist(this.getDomainObjectConditionalStyle());
|
||||
}
|
||||
},
|
||||
getDomainObjectConditionalStyle() {
|
||||
getDomainObjectConditionalStyle(defaultConditionId) {
|
||||
let objectStyle = {
|
||||
styles: this.conditionalStyles,
|
||||
staticStyle: this.staticStyle
|
||||
staticStyle: this.staticStyle,
|
||||
selectedConditionId: this.selectedConditionId
|
||||
};
|
||||
if (defaultConditionId) {
|
||||
objectStyle.defaultConditionId = defaultConditionId;
|
||||
}
|
||||
if (this.conditionSetDomainObject) {
|
||||
objectStyle.conditionSetIdentifier = this.conditionSetDomainObject.identifier;
|
||||
}
|
||||
@@ -393,6 +446,10 @@ export default {
|
||||
getCondition(id) {
|
||||
return this.conditions ? this.conditions[id] : {};
|
||||
},
|
||||
applySelectedConditionStyle(conditionId) {
|
||||
this.selectedConditionId = conditionId;
|
||||
this.persist(this.getDomainObjectConditionalStyle());
|
||||
},
|
||||
persist(style) {
|
||||
this.openmct.objects.mutate(this.domainObject, 'configuration.objectStyles', style);
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
import StyleEditor from "./StyleEditor.vue";
|
||||
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||
import { getApplicableStylesForItem, getConsolidatedStyleValues, getConditionalStyleForItem } from "@/plugins/condition/utils/styleUtils";
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
export default {
|
||||
name: 'MultiSelectStylesView',
|
||||
@@ -178,7 +179,7 @@ export default {
|
||||
domainObjectStyles[itemId] = undefined;
|
||||
delete domainObjectStyles[this.itemId];
|
||||
|
||||
if (_.isEmpty(domainObjectStyles)) {
|
||||
if (isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
this.persist(this.domainObject, domainObjectStyles);
|
||||
@@ -239,7 +240,7 @@ export default {
|
||||
if (this.isStaticAndConditionalStyles) {
|
||||
this.removeConditionalStyles(domainObjectStyles, item.id);
|
||||
}
|
||||
if (_.isEmpty(itemStaticStyle)) {
|
||||
if (isEmpty(itemStaticStyle)) {
|
||||
itemStaticStyle = undefined;
|
||||
domainObjectStyles[item.id] = undefined;
|
||||
} else {
|
||||
|
||||
@@ -60,6 +60,31 @@
|
||||
|
||||
&__condition {
|
||||
@include discreteItem();
|
||||
border: 1px solid transparent;
|
||||
pointer-events: none; // Prevent selecting when the object isn't being edited
|
||||
|
||||
&.is-current {
|
||||
$c: $colorBodyFg;
|
||||
border-color: rgba($c, 0.2);
|
||||
background: rgba($c, 0.2);
|
||||
}
|
||||
|
||||
.is-editing & {
|
||||
cursor: pointer;
|
||||
pointer-events: initial;
|
||||
transition: $transOut;
|
||||
|
||||
&:hover {
|
||||
background: rgba($colorBodyFg, 0.1);
|
||||
transition: $transIn;
|
||||
}
|
||||
|
||||
&.is-current {
|
||||
$c: $editUIColorBg;
|
||||
border-color: $c;
|
||||
background: rgba($c, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-style {
|
||||
|
||||
@@ -20,25 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import { createOpenMct } from "testTools";
|
||||
import { createOpenMct } from "testUtils";
|
||||
import ConditionPlugin from "./plugin";
|
||||
|
||||
let openmct = createOpenMct();
|
||||
openmct.install(new ConditionPlugin());
|
||||
|
||||
let conditionSetDefinition;
|
||||
let mockConditionSetDomainObject;
|
||||
let element;
|
||||
let child;
|
||||
|
||||
describe('the plugin', function () {
|
||||
let conditionSetDefinition;
|
||||
let mockConditionSetDomainObject;
|
||||
let element;
|
||||
let child;
|
||||
let openmct;
|
||||
|
||||
beforeAll((done) => {
|
||||
openmct = createOpenMct();
|
||||
openmct.install(new ConditionPlugin());
|
||||
|
||||
conditionSetDefinition = openmct.types.get('conditionSet').definition;
|
||||
const appHolder = document.createElement('div');
|
||||
appHolder.style.width = '640px';
|
||||
appHolder.style.height = '480px';
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
@@ -55,7 +51,7 @@ describe('the plugin', function () {
|
||||
conditionSetDefinition.initialize(mockConditionSetDomainObject);
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(appHolder);
|
||||
openmct.startHeadless();
|
||||
});
|
||||
|
||||
let mockConditionSetObject = {
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
const convertToNumbers = (input) => {
|
||||
let numberInputs = [];
|
||||
input.forEach(inputValue => numberInputs.push(Number(inputValue)));
|
||||
@@ -257,7 +255,7 @@ export const OPERATIONS = [
|
||||
const lhsValue = input[0] !== undefined ? input[0].toString() : '';
|
||||
if (input[1]) {
|
||||
const values = input[1].split(',');
|
||||
return values.find((value) => lhsValue === _.trim(value.toString()));
|
||||
return values.find((value) => lhsValue === value.toString().trim());
|
||||
}
|
||||
return false;
|
||||
},
|
||||
@@ -274,7 +272,7 @@ export const OPERATIONS = [
|
||||
const lhsValue = input[0] !== undefined ? input[0].toString() : '';
|
||||
if (input[1]) {
|
||||
const values = input[1].split(',');
|
||||
const found = values.find((value) => lhsValue === _.trim(value.toString()));
|
||||
const found = values.find((value) => lhsValue === value.toString().trim());
|
||||
return !found;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
const NONE_VALUE = '__no_value';
|
||||
|
||||
const styleProps = {
|
||||
@@ -154,7 +156,7 @@ export const getApplicableStylesForItem = (domainObject, item) => {
|
||||
};
|
||||
|
||||
export const getStylesWithoutNoneValue = (style) => {
|
||||
if (_.isEmpty(style) || !style) {
|
||||
if (isEmpty(style) || !style) {
|
||||
return;
|
||||
}
|
||||
let styleObj = {};
|
||||
|
||||
@@ -68,7 +68,6 @@
|
||||
|
||||
<script>
|
||||
import uuid from 'uuid';
|
||||
|
||||
import SubobjectView from './SubobjectView.vue'
|
||||
import TelemetryView from './TelemetryView.vue'
|
||||
import BoxView from './BoxView.vue'
|
||||
@@ -76,6 +75,7 @@ import TextView from './TextView.vue'
|
||||
import LineView from './LineView.vue'
|
||||
import ImageView from './ImageView.vue'
|
||||
import EditMarquee from './EditMarquee.vue'
|
||||
import _ from 'lodash'
|
||||
|
||||
const ITEM_TYPE_VIEW_MAP = {
|
||||
'subobject-view': SubobjectView,
|
||||
@@ -512,7 +512,7 @@ export default {
|
||||
}
|
||||
},
|
||||
updateTelemetryFormat(item, format) {
|
||||
let index = _.findIndex(this.layoutItems, item);
|
||||
let index = this.layoutItems.findIndex(item);
|
||||
item.format = format;
|
||||
this.mutate(`configuration.items[${index}]`, item);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
|
||||
<script>
|
||||
import LayoutDrag from './../LayoutDrag'
|
||||
import _ from 'lodash'
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<script>
|
||||
|
||||
import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
import _ from 'lodash';
|
||||
|
||||
const START_HANDLE_QUADRANTS = {
|
||||
1: 'c-frame-edit__handle--sw',
|
||||
|
||||
@@ -52,7 +52,7 @@ export default {
|
||||
},
|
||||
initObjectStyles() {
|
||||
if (!this.styleRuleManager) {
|
||||
this.styleRuleManager = new StyleRuleManager(this.objectStyle, this.openmct, this.updateStyle.bind(this));
|
||||
this.styleRuleManager = new StyleRuleManager(this.objectStyle, this.openmct, this.updateStyle.bind(this), true);
|
||||
} else {
|
||||
this.styleRuleManager.updateObjectStyleConfig(this.objectStyle);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
import Layout from './components/DisplayLayout.vue'
|
||||
import Vue from 'vue'
|
||||
import objectUtils from '../../api/objects/object-utils.js'
|
||||
import objectUtils from 'objectUtils'
|
||||
import DisplayLayoutType from './DisplayLayoutType.js'
|
||||
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
|
||||
import AlphaNumericFormatViewProvider from './AlphanumericFormatViewProvider.js'
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<script>
|
||||
import FilterField from './FilterField.vue';
|
||||
import ToggleSwitch from '../../../ui/components/ToggleSwitch.vue';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
@@ -102,7 +103,7 @@ export default {
|
||||
hasActiveFilters() {
|
||||
// Should be true when the user has entered any filter values.
|
||||
return Object.values(this.persistedFilters).some(comparator => {
|
||||
return (typeof(comparator) === 'object' && !_.isEmpty(comparator));
|
||||
return (typeof(comparator) === 'object' && !isEmpty(comparator));
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
|
||||
<script>
|
||||
import FilterObject from './FilterObject.vue';
|
||||
import GlobalFilters from './GlobalFilters.vue'
|
||||
import GlobalFilters from './GlobalFilters.vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
const FILTER_VIEW_TITLE = 'Filters applied';
|
||||
const FILTER_VIEW_TITLE_MIXED = 'Mixed filters applied';
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
<script>
|
||||
import compositionLoader from './composition-loader';
|
||||
import ListItem from './ListItem.vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
export default {
|
||||
components: {ListItem},
|
||||
|
||||
@@ -220,7 +220,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
const index = _.sortedIndex(this.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
|
||||
const index = _.sortedIndexBy(this.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
|
||||
this.imageHistory.splice(index, 0, datum);
|
||||
},
|
||||
updateValues(datum) {
|
||||
|
||||
@@ -162,19 +162,32 @@ export default {
|
||||
}).show(this.embed.snapshot.src);
|
||||
},
|
||||
changeLocation() {
|
||||
this.openmct.time.stopClock();
|
||||
this.openmct.time.bounds({
|
||||
start: this.embed.bounds.start,
|
||||
end: this.embed.bounds.end
|
||||
});
|
||||
|
||||
const link = this.embed.historicLink;
|
||||
if (!link) {
|
||||
return;
|
||||
}
|
||||
|
||||
const bounds = this.openmct.time.bounds();
|
||||
const isTimeBoundChanged = this.embed.bounds.start !== bounds.start
|
||||
&& this.embed.bounds.end !== bounds.end;
|
||||
const isFixedTimespanMode = !this.openmct.time.clock();
|
||||
|
||||
this.openmct.time.stopClock();
|
||||
window.location.href = link;
|
||||
const message = 'Time bounds changed to fixed timespan mode';
|
||||
|
||||
let message = '';
|
||||
if (isTimeBoundChanged) {
|
||||
this.openmct.time.bounds({
|
||||
start: this.embed.bounds.start,
|
||||
end: this.embed.bounds.end
|
||||
});
|
||||
message = 'Time bound values changed';
|
||||
}
|
||||
|
||||
if (!isFixedTimespanMode) {
|
||||
message = 'Time bound values changed to fixed timespan mode';
|
||||
}
|
||||
|
||||
this.openmct.notifications.alert(message);
|
||||
},
|
||||
formatTime(unixTime, timeFormat) {
|
||||
|
||||
@@ -221,7 +221,7 @@ export default {
|
||||
return position;
|
||||
},
|
||||
formatTime(unixTime, timeFormat) {
|
||||
return Moment(unixTime).format(timeFormat);
|
||||
return Moment.utc(unixTime).format(timeFormat);
|
||||
},
|
||||
moveSnapshot(snapshotId) {
|
||||
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<script>
|
||||
import Snapshot from '../snapshot';
|
||||
import { clearDefaultNotebook, getDefaultNotebook } from '../utils/notebook-storage';
|
||||
import { getDefaultNotebook } from '../utils/notebook-storage';
|
||||
import { NOTEBOOK_DEFAULT, NOTEBOOK_SNAPSHOT } from '../notebook-constants';
|
||||
|
||||
export default {
|
||||
@@ -40,6 +40,18 @@ export default {
|
||||
default() {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
ignoreLink: {
|
||||
type: Boolean,
|
||||
default() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
default() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -60,28 +72,22 @@ export default {
|
||||
methods: {
|
||||
async setNotebookTypes() {
|
||||
const notebookTypes = [];
|
||||
let defaultPath = '';
|
||||
const defaultNotebook = getDefaultNotebook();
|
||||
|
||||
if (defaultNotebook) {
|
||||
const domainObject = await this.openmct.objects.get(defaultNotebook.notebookMeta.identifier)
|
||||
.then(d => d);
|
||||
const domainObject = defaultNotebook.domainObject;
|
||||
|
||||
if (!domainObject.location) {
|
||||
clearDefaultNotebook();
|
||||
} else {
|
||||
defaultPath = `${domainObject.name} - ${defaultNotebook.section.name} - ${defaultNotebook.page.name}`;
|
||||
if (domainObject.location) {
|
||||
const defaultPath = `${domainObject.name} - ${defaultNotebook.section.name} - ${defaultNotebook.page.name}`;
|
||||
|
||||
notebookTypes.push({
|
||||
cssClass: 'icon-notebook',
|
||||
name: `Save to Notebook ${defaultPath}`,
|
||||
type: NOTEBOOK_DEFAULT
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (defaultPath.length !== 0) {
|
||||
notebookTypes.push({
|
||||
cssClass: 'icon-notebook',
|
||||
name: `Save to Notebook ${defaultPath}`,
|
||||
type: NOTEBOOK_DEFAULT
|
||||
});
|
||||
}
|
||||
|
||||
notebookTypes.push({
|
||||
cssClass: 'icon-notebook',
|
||||
name: 'Save to Notebook Snapshots',
|
||||
@@ -97,17 +103,27 @@ export default {
|
||||
this.showMenu = false;
|
||||
},
|
||||
snapshot(notebook) {
|
||||
let element = document.getElementsByClassName("l-shell__main-container")[0];
|
||||
const bounds = this.openmct.time.bounds();
|
||||
const objectPath = this.openmct.router.path;
|
||||
const snapshotMeta = {
|
||||
bounds,
|
||||
link: window.location.href,
|
||||
objectPath,
|
||||
openmct: this.openmct
|
||||
};
|
||||
this.hideMenu();
|
||||
|
||||
this.notebookSnapshot.capture(snapshotMeta, notebook.type, element);
|
||||
this.$nextTick(() => {
|
||||
const element = document.querySelector('.c-overlay__contents')
|
||||
|| document.getElementsByClassName('l-shell__main-container')[0];
|
||||
|
||||
const bounds = this.openmct.time.bounds();
|
||||
const link = !this.ignoreLink
|
||||
? window.location.href
|
||||
: null;
|
||||
|
||||
const objectPath = this.objectPath || this.openmct.router.path;
|
||||
const snapshotMeta = {
|
||||
bounds,
|
||||
link,
|
||||
objectPath,
|
||||
openmct: this.openmct
|
||||
};
|
||||
|
||||
this.notebookSnapshot.capture(snapshotMeta, notebook.type, element);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,6 +239,7 @@ export default {
|
||||
const section = this.getSelectedSection();
|
||||
|
||||
return {
|
||||
domainObject: this.internalDomainObject,
|
||||
notebookMeta,
|
||||
section,
|
||||
page
|
||||
@@ -440,7 +441,7 @@ export default {
|
||||
async updateDefaultNotebook(notebookStorage) {
|
||||
const defaultNotebookObject = await this.getDefaultNotebookObject();
|
||||
this.removeDefaultClass(defaultNotebookObject);
|
||||
setDefaultNotebook(notebookStorage);
|
||||
setDefaultNotebook(this.openmct, notebookStorage);
|
||||
this.addDefaultClass();
|
||||
this.defaultSectionId = notebookStorage.section.id;
|
||||
this.defaultPageId = notebookStorage.page.id;
|
||||
@@ -495,7 +496,7 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
if (section.id !== defaultNotebookSection.id) {
|
||||
if (id !== defaultNotebookSection.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,46 @@
|
||||
const NOTEBOOK_LOCAL_STORAGE = 'notebook-storage';
|
||||
let currentNotebookObject = null;
|
||||
let unlisten = null;
|
||||
|
||||
function defaultNotebookObjectChanged(newDomainObject) {
|
||||
if (newDomainObject.location !== null) {
|
||||
currentNotebookObject = newDomainObject;
|
||||
const notebookStorage = getDefaultNotebook();
|
||||
notebookStorage.domainObject = newDomainObject;
|
||||
saveDefaultNotebook(notebookStorage);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlisten) {
|
||||
unlisten();
|
||||
unlisten = null;
|
||||
}
|
||||
|
||||
clearDefaultNotebook();
|
||||
}
|
||||
|
||||
function observeDefaultNotebookObject(openmct, notebookStorage) {
|
||||
const domainObject = notebookStorage.domainObject;
|
||||
if (currentNotebookObject
|
||||
&& currentNotebookObject.identifier.key === domainObject.identifier.key) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (unlisten) {
|
||||
unlisten();
|
||||
unlisten = null;
|
||||
}
|
||||
|
||||
unlisten = openmct.objects.observe(notebookStorage.domainObject, '*', defaultNotebookObjectChanged);
|
||||
}
|
||||
|
||||
function saveDefaultNotebook(notebookStorage) {
|
||||
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage));
|
||||
}
|
||||
|
||||
export function clearDefaultNotebook() {
|
||||
currentNotebookObject = null;
|
||||
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, null);
|
||||
}
|
||||
|
||||
@@ -10,20 +50,21 @@ export function getDefaultNotebook() {
|
||||
return JSON.parse(notebookStorage);
|
||||
}
|
||||
|
||||
export function setDefaultNotebook(notebookStorage) {
|
||||
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage));
|
||||
export function setDefaultNotebook(openmct, notebookStorage) {
|
||||
observeDefaultNotebookObject(openmct, notebookStorage);
|
||||
saveDefaultNotebook(notebookStorage);
|
||||
}
|
||||
|
||||
export function setDefaultNotebookSection(section) {
|
||||
const notebookStorage = getDefaultNotebook();
|
||||
|
||||
notebookStorage.section = section;
|
||||
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage));
|
||||
saveDefaultNotebook(notebookStorage);
|
||||
|
||||
}
|
||||
|
||||
export function setDefaultNotebookPage(page) {
|
||||
const notebookStorage = getDefaultNotebook();
|
||||
notebookStorage.page = page;
|
||||
window.localStorage.setItem(NOTEBOOK_LOCAL_STORAGE, JSON.stringify(notebookStorage));
|
||||
saveDefaultNotebook(notebookStorage);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
-->
|
||||
<div ng-controller="StackedPlotController as stackedPlot"
|
||||
class="c-plot c-plot--stacked holder holder-plot has-control-bar">
|
||||
<div class="l-control-bar" ng-show="!stackedPlot.hideExportButtons">
|
||||
<div class="c-control-bar" ng-show="!stackedPlot.hideExportButtons">
|
||||
<span class="c-button-set c-button-set--strip-h">
|
||||
<button class="c-button icon-download"
|
||||
ng-click="stackedPlot.exportPNG()"
|
||||
|
||||
@@ -152,7 +152,7 @@ function (
|
||||
MCTChartController.prototype.destroy = function () {
|
||||
this.isDestroyed = true;
|
||||
this.stopListening();
|
||||
_.invoke(this.lines, 'destroy');
|
||||
this.lines.forEach(line => line.destroy());
|
||||
DrawLoader.releaseDrawAPI(this.drawAPI);
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ define([
|
||||
this.initialize(options);
|
||||
}
|
||||
|
||||
_.extend(Collection.prototype, EventEmitter.prototype);
|
||||
Object.assign(Collection.prototype, EventEmitter.prototype);
|
||||
eventHelpers.extend(Collection.prototype);
|
||||
|
||||
Collection.extend = extend;
|
||||
@@ -105,12 +105,7 @@ define([
|
||||
};
|
||||
|
||||
Collection.prototype.indexOf = function (model) {
|
||||
return _.findIndex(
|
||||
this.models,
|
||||
function (m) {
|
||||
return m === model;
|
||||
}
|
||||
);
|
||||
return this.models.findIndex(m => m === model);
|
||||
};
|
||||
|
||||
Collection.prototype.remove = function (model) {
|
||||
|
||||
@@ -49,7 +49,7 @@ define([
|
||||
this.initialize(options);
|
||||
}
|
||||
|
||||
_.extend(Model.prototype, EventEmitter.prototype);
|
||||
Object.assign(Model.prototype, EventEmitter.prototype);
|
||||
eventHelpers.extend(Model.prototype);
|
||||
|
||||
Model.extend = extend;
|
||||
|
||||
@@ -146,7 +146,7 @@ define([
|
||||
strategy = 'minmax';
|
||||
}
|
||||
|
||||
options = _.extend({}, { size: 1000, strategy, filters: this.filters }, options || {});
|
||||
options = Object.assign({}, { size: 1000, strategy, filters: this.filters }, options || {});
|
||||
|
||||
if (!this.unsubscribe) {
|
||||
this.unsubscribe = this.openmct
|
||||
@@ -160,6 +160,7 @@ define([
|
||||
);
|
||||
}
|
||||
|
||||
/* eslint-disable you-dont-need-lodash-underscore/concat */
|
||||
return this.openmct
|
||||
.telemetry
|
||||
.request(this.domainObject, options)
|
||||
@@ -171,6 +172,7 @@ define([
|
||||
.value();
|
||||
this.reset(newPoints);
|
||||
}.bind(this));
|
||||
/* eslint-enable you-dont-need-lodash-underscore/concat */
|
||||
},
|
||||
/**
|
||||
* Update x formatter on x change.
|
||||
@@ -270,7 +272,7 @@ define([
|
||||
* @private
|
||||
*/
|
||||
sortedIndex: function (point) {
|
||||
return _.sortedIndex(this.data, point, this.getXVal);
|
||||
return _.sortedIndexBy(this.data, point, this.getXVal);
|
||||
},
|
||||
/**
|
||||
* Update min/max stats for the series.
|
||||
|
||||
@@ -101,11 +101,11 @@ define([
|
||||
var plotObject = this.plot.get('domainObject');
|
||||
if (plotObject.type === 'telemetry.plot.overlay') {
|
||||
|
||||
var persistedIndex = _.findIndex(plotObject.configuration.series, function (s) {
|
||||
var persistedIndex = plotObject.configuration.series.findIndex(s => {
|
||||
return _.isEqual(identifier, s.identifier);
|
||||
});
|
||||
|
||||
var configIndex = _.findIndex(this.models, function (m) {
|
||||
var configIndex = this.models.findIndex(m => {
|
||||
return _.isEqual(m.domainObject.identifier, identifier);
|
||||
});
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
_.extend(Draw2D.prototype, EventEmitter.prototype);
|
||||
Object.assign(Draw2D.prototype, EventEmitter.prototype);
|
||||
eventHelpers.extend(Draw2D.prototype);
|
||||
|
||||
// Convert from logical to physical x coordinates
|
||||
|
||||
@@ -78,7 +78,7 @@ define([
|
||||
this.listenTo(this.canvas, "webglcontextlost", this.onContextLost, this);
|
||||
}
|
||||
|
||||
_.extend(DrawWebGL.prototype, EventEmitter.prototype);
|
||||
Object.assign(DrawWebGL.prototype, EventEmitter.prototype);
|
||||
eventHelpers.extend(DrawWebGL.prototype);
|
||||
|
||||
DrawWebGL.prototype.onContextLost = function (event) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
define([
|
||||
'../configuration/configStore',
|
||||
'../lib/eventHelpers',
|
||||
'../../../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
], function (
|
||||
configStore,
|
||||
|
||||
@@ -31,7 +31,7 @@ define([
|
||||
function dynamicPathForKey(key) {
|
||||
return function (object, model) {
|
||||
var modelIdentifier = model.get('identifier');
|
||||
var index = _.findIndex(object.configuration.series, function (s) {
|
||||
var index = object.configuration.series.findIndex(s => {
|
||||
return _.isEqual(s.identifier, modelIdentifier);
|
||||
});
|
||||
return 'configuration.series[' + index + '].' + key;
|
||||
|
||||
@@ -73,10 +73,10 @@ define([
|
||||
if (range.max === '' || range.max === null || typeof range.max === 'undefined') {
|
||||
return 'Must specify Maximum';
|
||||
}
|
||||
if (_.isNaN(Number(range.min))) {
|
||||
if (Number.isNaN(Number(range.min))) {
|
||||
return 'Minimum must be a number.';
|
||||
}
|
||||
if (_.isNaN(Number(range.max))) {
|
||||
if (Number.isNaN(Number(range.max))) {
|
||||
return 'Maximum must be a number.';
|
||||
}
|
||||
if (Number(range.min) > Number(range.max)) {
|
||||
|
||||
@@ -67,10 +67,10 @@ define([
|
||||
}
|
||||
this.$canvas = this.$element.find('canvas');
|
||||
|
||||
this.listenTo(this.$canvas, 'click', this.onMouseClick, this);
|
||||
this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this);
|
||||
this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this);
|
||||
this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this);
|
||||
this.listenTo(this.$canvas, 'wheel', this.wheelZoom, this);
|
||||
|
||||
this.watchForMarquee();
|
||||
};
|
||||
@@ -78,7 +78,6 @@ define([
|
||||
MCTPlotController.prototype.initialize = function () {
|
||||
this.$canvas = this.$element.find('canvas');
|
||||
|
||||
this.listenTo(this.$canvas, 'click', this.onMouseClick, this);
|
||||
this.listenTo(this.$canvas, 'mousemove', this.trackMousePosition, this);
|
||||
this.listenTo(this.$canvas, 'mouseleave', this.untrackMousePosition, this);
|
||||
this.listenTo(this.$canvas, 'mousedown', this.onMouseDown, this);
|
||||
@@ -210,23 +209,6 @@ define([
|
||||
this.highlightValues(point);
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.onMouseClick = function ($event) {
|
||||
const isClick = this.isMouseClick();
|
||||
if (this.pan) {
|
||||
this.endPan($event);
|
||||
}
|
||||
if (this.marquee) {
|
||||
this.endMarquee($event);
|
||||
}
|
||||
this.$scope.$apply();
|
||||
|
||||
if (!this.$scope.highlights.length || !isClick) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.$scope.lockHighlightPoint = !this.$scope.lockHighlightPoint;
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.highlightValues = function (point) {
|
||||
this.highlightPoint = point;
|
||||
this.$scope.$emit('plot:highlight:update', point);
|
||||
@@ -274,11 +256,23 @@ define([
|
||||
MCTPlotController.prototype.onMouseUp = function ($event) {
|
||||
this.stopListening(this.$window, 'mouseup', this.onMouseUp, this);
|
||||
this.stopListening(this.$window, 'mousemove', this.trackMousePosition, this);
|
||||
|
||||
if (this.isMouseClick()) {
|
||||
this.$scope.lockHighlightPoint = !this.$scope.lockHighlightPoint;
|
||||
}
|
||||
|
||||
if (this.allowPan) {
|
||||
return this.endPan($event);
|
||||
}
|
||||
|
||||
if (this.allowMarquee) {
|
||||
return this.endMarquee($event);
|
||||
}
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.isMouseClick = function () {
|
||||
if (!this.marquee) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
const { start, end } = this.marquee;
|
||||
@@ -331,7 +325,7 @@ define([
|
||||
} else {
|
||||
// A history entry is created by startMarquee, need to remove
|
||||
// if marquee zoom doesn't occur.
|
||||
this.back();
|
||||
this.plotHistory.pop();
|
||||
}
|
||||
this.$scope.rectangles = [];
|
||||
this.marquee = undefined;
|
||||
|
||||
@@ -81,7 +81,8 @@ define(
|
||||
clonedElement.classList.add(className);
|
||||
}
|
||||
element.id = oldId;
|
||||
}
|
||||
},
|
||||
removeContainer: true // Set to false to debug what html2canvas renders
|
||||
}).then(function (canvas) {
|
||||
dialog.dismiss();
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
@@ -227,8 +227,9 @@ define([
|
||||
};
|
||||
|
||||
PlotController.prototype.stopLoading = function () {
|
||||
this.$scope.pending -= 1;
|
||||
this.$scope.$digest();
|
||||
this.$scope.$evalAsync(() => {
|
||||
this.$scope.pending -= 1;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -76,7 +76,7 @@ define([
|
||||
if (childObj) {
|
||||
var index = telemetryObjects.indexOf(childObj);
|
||||
telemetryObjects.splice(index, 1);
|
||||
$scope.$broadcast('plot:tickWidth', _.max(tickWidthMap));
|
||||
$scope.$broadcast('plot:tickWidth', Math.max(...Object.values(tickWidthMap)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define([
|
||||
'../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
objectUtils
|
||||
) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
define ([
|
||||
'./ConditionEvaluator',
|
||||
'../../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'EventEmitter',
|
||||
'zepto',
|
||||
'lodash'
|
||||
@@ -9,7 +9,8 @@ define ([
|
||||
objectUtils,
|
||||
EventEmitter,
|
||||
$,
|
||||
_
|
||||
_,
|
||||
|
||||
) {
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ define([
|
||||
'./TestDataManager',
|
||||
'./WidgetDnD',
|
||||
'./eventHelpers',
|
||||
'../../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash',
|
||||
'zepto'
|
||||
], function (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
define([
|
||||
'./Select',
|
||||
'../../../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
Select,
|
||||
objectUtils
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
define([
|
||||
'./SummaryWidgetEvaluator',
|
||||
'../../../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
SummaryWidgetEvaluator,
|
||||
objectUtils
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
define([
|
||||
'./SummaryWidgetRule',
|
||||
'../eventHelpers',
|
||||
'../../../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'lodash'
|
||||
], function (
|
||||
SummaryWidgetRule,
|
||||
@@ -80,10 +80,12 @@ define([
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
/* eslint-disable you-dont-need-lodash-underscore/map */
|
||||
unsubscribes = _.map(
|
||||
realtimeStates,
|
||||
this.subscribeToObjectState.bind(this, updateCallback)
|
||||
);
|
||||
/* eslint-enable you-dont-need-lodash-underscore/map */
|
||||
}.bind(this));
|
||||
|
||||
return function () {
|
||||
@@ -151,11 +153,13 @@ define([
|
||||
SummaryWidgetEvaluator.prototype.getBaseStateClone = function () {
|
||||
return this.load()
|
||||
.then(function () {
|
||||
/* eslint-disable you-dont-need-lodash-underscore/values */
|
||||
return _(this.baseState)
|
||||
.values()
|
||||
.map(_.clone)
|
||||
.indexBy('id')
|
||||
.keyBy('id')
|
||||
.value();
|
||||
/* eslint-enable you-dont-need-lodash-underscore/values */
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
@@ -182,7 +186,7 @@ define([
|
||||
* @private.
|
||||
*/
|
||||
SummaryWidgetEvaluator.prototype.updateObjectStateFromLAD = function (options, objectState) {
|
||||
options = _.extend({}, options, {
|
||||
options = Object.assign({}, options, {
|
||||
strategy: 'latest',
|
||||
size: 1
|
||||
});
|
||||
@@ -255,10 +259,12 @@ define([
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-disable you-dont-need-lodash-underscore/map */
|
||||
var latestTimestamp = _(state)
|
||||
.map('timestamps')
|
||||
.sortBy(timestampKey)
|
||||
.last();
|
||||
/* eslint-enable you-dont-need-lodash-underscore/map */
|
||||
|
||||
if (!latestTimestamp) {
|
||||
latestTimestamp = {};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
define([
|
||||
'../SummaryWidget',
|
||||
'./SummaryWidgetView',
|
||||
'../../../../api/objects/object-utils'
|
||||
'objectUtils'
|
||||
], function (
|
||||
SummaryWidgetEditView,
|
||||
SummaryWidgetView,
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
{'is-current': isCurrent(tab)},
|
||||
tab.type.definition.cssClass
|
||||
]"
|
||||
@click="showTab(tab)"
|
||||
@click="showTab(tab, index)"
|
||||
>
|
||||
<span class="c-button__label">{{ tab.domainObject.name }}</span>
|
||||
</button>
|
||||
@@ -48,6 +48,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<object-view
|
||||
v-if="internalDomainObject.keep_alive ? currentTab : isCurrent(tab)"
|
||||
class="c-tabs-view__object"
|
||||
:object="tab.domainObject"
|
||||
/>
|
||||
@@ -57,7 +58,6 @@
|
||||
|
||||
<script>
|
||||
import ObjectView from '../../../ui/components/ObjectView.vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
var unknownObjectType = {
|
||||
definition: {
|
||||
@@ -73,6 +73,7 @@ export default {
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
internalDomainObject: this.domainObject,
|
||||
currentTab: {},
|
||||
tabsList: [],
|
||||
setCurrentTab: true,
|
||||
@@ -85,9 +86,17 @@ export default {
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.onReorder);
|
||||
this.composition.load();
|
||||
this.composition.load().then(() => {
|
||||
let currentTabIndex = this.domainObject.currentTabIndex;
|
||||
|
||||
if (currentTabIndex !== undefined && this.tabsList.length > currentTabIndex) {
|
||||
this.currentTab = this.tabsList[currentTabIndex];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
this.unsubscribe = this.openmct.objects.observe(this.internalDomainObject, '*', this.updateInternalDomainObject);
|
||||
|
||||
document.addEventListener('dragstart', this.dragstart);
|
||||
document.addEventListener('dragend', this.dragend);
|
||||
},
|
||||
@@ -96,18 +105,25 @@ export default {
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.onReorder);
|
||||
|
||||
this.unsubscribe();
|
||||
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
},
|
||||
methods:{
|
||||
showTab(tab) {
|
||||
showTab(tab, index) {
|
||||
if (index !== undefined) {
|
||||
this.storeCurrentTabIndex(index);
|
||||
}
|
||||
|
||||
this.currentTab = tab;
|
||||
},
|
||||
addItem(domainObject) {
|
||||
let type = this.openmct.types.get(domainObject.type) || unknownObjectType,
|
||||
tabItem = {
|
||||
domainObject,
|
||||
type: type
|
||||
type: type,
|
||||
key: this.openmct.objects.makeKeyString(domainObject.identifier)
|
||||
};
|
||||
|
||||
this.tabsList.push(tabItem);
|
||||
@@ -126,7 +142,7 @@ export default {
|
||||
this.tabsList.splice(pos, 1);
|
||||
|
||||
if (this.isCurrent(tabToBeRemoved)) {
|
||||
this.showTab(this.tabsList[this.tabsList.length - 1]);
|
||||
this.showTab(this.tabsList[this.tabsList.length - 1], this.tabsList.length - 1);
|
||||
}
|
||||
},
|
||||
onReorder(reorderPlan) {
|
||||
@@ -138,6 +154,7 @@ export default {
|
||||
},
|
||||
onDrop(e) {
|
||||
this.setCurrentTab = true;
|
||||
this.storeCurrentTabIndex(this.tabsList.length);
|
||||
},
|
||||
dragstart(e) {
|
||||
if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
@@ -155,7 +172,13 @@ export default {
|
||||
this.allowDrop = false;
|
||||
},
|
||||
isCurrent(tab) {
|
||||
return _.isEqual(this.currentTab, tab)
|
||||
return this.currentTab.key === tab.key;
|
||||
},
|
||||
updateInternalDomainObject(domainObject) {
|
||||
this.internalDomainObject = domainObject;
|
||||
},
|
||||
storeCurrentTabIndex(index) {
|
||||
this.openmct.objects.mutate(this.internalDomainObject, 'currentTabIndex', index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,27 @@ define([
|
||||
cssClass: 'icon-tabs-view',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
}
|
||||
domainObject.keep_alive = true;
|
||||
},
|
||||
form: [
|
||||
{
|
||||
"key": "keep_alive",
|
||||
"name": "Keep Tabs Alive",
|
||||
"control": "select",
|
||||
"options": [
|
||||
{
|
||||
'name': 'True',
|
||||
'value': true
|
||||
},
|
||||
{
|
||||
'name': 'False',
|
||||
'value': false
|
||||
}
|
||||
],
|
||||
"required": true,
|
||||
"cssClass": "l-input"
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
/*jshint latedef: nofunc */
|
||||
/*global console */
|
||||
define([
|
||||
'../../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'./TelemetryAverager'
|
||||
], function (objectUtils, TelemetryAverager) {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'../../api/objects/object-utils',
|
||||
'objectUtils',
|
||||
'./components/table-configuration.vue',
|
||||
'./TelemetryTableConfiguration',
|
||||
'vue'
|
||||
|
||||
@@ -100,7 +100,7 @@ define([
|
||||
|
||||
hasColumnWithKey(columnKey) {
|
||||
return _.flatten(Object.values(this.columns))
|
||||
.findIndex(column => column.getKey() === columnKey) !== -1;
|
||||
.some(column => column.getKey() === columnKey);
|
||||
}
|
||||
|
||||
getColumns() {
|
||||
@@ -109,9 +109,10 @@ define([
|
||||
|
||||
getAllHeaders() {
|
||||
let flattenedColumns = _.flatten(Object.values(this.columns));
|
||||
/* eslint-disable you-dont-need-lodash-underscore/uniq */
|
||||
let headers = _.uniq(flattenedColumns, false, column => column.getKey())
|
||||
.reduce(fromColumnsToHeadersMap, {});
|
||||
|
||||
/* eslint-enable you-dont-need-lodash-underscore/uniq */
|
||||
function fromColumnsToHeadersMap(headersMap, column) {
|
||||
headersMap[column.getKey()] = column.getTitle();
|
||||
return headersMap;
|
||||
|
||||
@@ -93,7 +93,7 @@ define(
|
||||
// same time stamp
|
||||
let potentialDupes = this.rows.slice(startIx, endIx + 1);
|
||||
// Search potential dupes for exact dupe
|
||||
isDuplicate = _.findIndex(potentialDupes, _.isEqual.bind(undefined, row)) > -1;
|
||||
isDuplicate = potentialDupes.some(_.isEqual.bind(undefined, row));
|
||||
}
|
||||
|
||||
if (!isDuplicate) {
|
||||
@@ -120,7 +120,7 @@ define(
|
||||
const firstValue = this.getValueForSortColumn(this.rows[0]);
|
||||
const lastValue = this.getValueForSortColumn(this.rows[this.rows.length - 1]);
|
||||
|
||||
lodashFunction = lodashFunction || _.sortedIndex;
|
||||
lodashFunction = lodashFunction || _.sortedIndexBy;
|
||||
|
||||
if (this.sortOptions.direction === 'asc') {
|
||||
if (testRowValue > lastValue) {
|
||||
@@ -201,7 +201,7 @@ define(
|
||||
sortBy(sortOptions) {
|
||||
if (arguments.length > 0) {
|
||||
this.sortOptions = sortOptions;
|
||||
this.rows = _.sortByOrder(this.rows, (row) => row.getParsedValue(sortOptions.key) , sortOptions.direction);
|
||||
this.rows = _.orderBy(this.rows, (row) => row.getParsedValue(sortOptions.key) , sortOptions.direction);
|
||||
this.emit('sort');
|
||||
}
|
||||
// Return duplicate to avoid direct modification of underlying object
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from 'lodash';
|
||||
|
||||
const FILTER_INDICATOR_LABEL = 'Filters:';
|
||||
const FILTER_INDICATOR_LABEL_MIXED = 'Mixed Filters:';
|
||||
const FILTER_INDICATOR_TITLE = 'Data filters are being applied to this view.';
|
||||
|
||||
@@ -165,7 +165,16 @@
|
||||
/******************************* LEGACY */
|
||||
.s-status-taking-snapshot,
|
||||
.overlay.snapshot {
|
||||
// Handle overflow-y issues with tables and html2canvas
|
||||
// Replaces .l-sticky-headers .l-tabular-body { overflow: auto; }
|
||||
.c-table__body-w { overflow: auto; }
|
||||
.c-table {
|
||||
&__body-w {
|
||||
overflow: auto; // Handle overflow-y issues with tables and html2canvas
|
||||
}
|
||||
|
||||
&-control-bar {
|
||||
display: none;
|
||||
+ * {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,34 +24,39 @@ import Vue from 'vue';
|
||||
import {
|
||||
createOpenMct,
|
||||
createMouseEvent
|
||||
} from 'testTools';
|
||||
|
||||
let openmct;
|
||||
let tablePlugin;
|
||||
let element;
|
||||
let child;
|
||||
} from 'testUtils';
|
||||
|
||||
describe("the plugin", () => {
|
||||
beforeEach((done) => {
|
||||
const appHolder = document.createElement('div');
|
||||
appHolder.style.width = '640px';
|
||||
appHolder.style.height = '480px';
|
||||
let openmct;
|
||||
let tablePlugin;
|
||||
let element;
|
||||
let child;
|
||||
|
||||
beforeEach((done) => {
|
||||
openmct = createOpenMct();
|
||||
|
||||
// Table Plugin is actually installed by default, but because installing it
|
||||
// again is harmless it is left here as an examplar for non-default plugins.
|
||||
tablePlugin = new TablePlugin();
|
||||
openmct.install(tablePlugin);
|
||||
|
||||
element = document.createElement('div');
|
||||
child = document.createElement('div');
|
||||
element.appendChild(child);
|
||||
|
||||
tablePlugin = new TablePlugin();
|
||||
openmct.install(tablePlugin);
|
||||
|
||||
spyOn(openmct.telemetry, 'request').and.returnValue(Promise.resolve([]));
|
||||
|
||||
openmct.on('start', done);
|
||||
openmct.start(appHolder);
|
||||
openmct.startHeadless();
|
||||
});
|
||||
|
||||
describe("defines a table object", function () {
|
||||
it("that is creatable", () => {
|
||||
let tableType = openmct.types.get('table');
|
||||
expect(tableType.definition.creatable).toBe(true);
|
||||
});
|
||||
})
|
||||
|
||||
it("provides a table view for objects with telemetry", () => {
|
||||
const testTelemetryObject = {
|
||||
id:"test-object",
|
||||
|
||||
@@ -565,6 +565,20 @@ select {
|
||||
}
|
||||
}
|
||||
}
|
||||
/******************************************************** CONTROL BARS */
|
||||
.c-control-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> * + * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** PALETTES */
|
||||
.c-palette {
|
||||
|
||||
@@ -40,28 +40,58 @@ mct-plot {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-plot,
|
||||
.gl-plot {
|
||||
.s-status-taking-snapshot & {
|
||||
.c-control-bar {
|
||||
display: none;
|
||||
}
|
||||
.gl-plot-y-label__select {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-plot {
|
||||
$p: $mainViewPad;
|
||||
position: absolute;
|
||||
top: $p; right: $p; bottom: $p; left: $p;
|
||||
//$p: $mainViewPad;
|
||||
@include abs($mainViewPad);
|
||||
//position: absolute;
|
||||
//top: $p; right: $p; bottom: $p; left: $p;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> * + * {
|
||||
margin-top: $interiorMargin;
|
||||
}
|
||||
|
||||
.l-control-bar {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.l-view-section {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&--stacked {
|
||||
.l-view-section {
|
||||
// Make this a flex container
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
.gl-plot.child-frame {
|
||||
mct-plot {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
flex: 1 1 auto;
|
||||
&:not(:first-child) {
|
||||
margin-top: $interiorMargin;
|
||||
.child-frame {
|
||||
.has-control-bar {
|
||||
.c-control-bar {
|
||||
// Hides buttons per plot element in a stacked plot
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
mct-plot {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.s-status-timeconductor-unsynced .holder-plot {
|
||||
@@ -70,7 +100,6 @@ mct-plot {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -186,7 +215,7 @@ mct-plot {
|
||||
left: 0; top: 0; right: auto; bottom: 0;
|
||||
padding-left: 5px;
|
||||
text-orientation: mixed;
|
||||
overflow: hidden;
|
||||
//overflow: hidden;
|
||||
writing-mode: vertical-lr;
|
||||
&:before {
|
||||
// Icon denoting configurability
|
||||
@@ -339,11 +368,11 @@ mct-plot {
|
||||
z-index: -10;
|
||||
|
||||
.l-view-section {
|
||||
$m: $interiorMargin;
|
||||
top: $m !important;
|
||||
right: $m;
|
||||
bottom: $m;
|
||||
left: $m;
|
||||
//$m: $interiorMargin;
|
||||
//top: $m !important;
|
||||
//right: $m;
|
||||
//bottom: $m;
|
||||
//left: $m;
|
||||
|
||||
.s-status-timeconductor-unsynced .holder-plot {
|
||||
.t-object-alert.t-alert-unsynced {
|
||||
|
||||
@@ -19,53 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/******************************************************************* VIEWS */
|
||||
// From _views.scss
|
||||
// Legacy overlay and stacked plots depend on this for now
|
||||
// Styles for sub-dividing views generically
|
||||
.l-control-bar {
|
||||
// Element that can be placed above l-view-section, holds controls, buttons, etc.
|
||||
height: $controlBarH;
|
||||
}
|
||||
|
||||
.c-control-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
> * + * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&__label {
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.l-view-section {
|
||||
@include abs();
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.has-control-bar {
|
||||
.l-view-section {
|
||||
top: $controlBarH + $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.child-frame {
|
||||
.has-control-bar {
|
||||
.l-control-bar,
|
||||
.c-control-bar {
|
||||
// Hides buttons per plot element in a stacked plot
|
||||
display: none;
|
||||
}
|
||||
.l-view-section {
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************** CLOCKS AND TIMERS */
|
||||
.c-clock,
|
||||
.c-timer {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user