Compare commits

...

36 Commits

Author SHA1 Message Date
Jamie V
e10e836796 allow before start bounds items while paging 2023-11-20 14:42:25 -08:00
Jamie V
ba688e667a suppress removal on bounds change while paging 2023-11-20 14:34:32 -08:00
Jamie V
9f309388fd suppress realtime while paging 2023-11-20 14:24:26 -08:00
Jamie V
c0ccc05361 was using a deleted domain object 2023-11-09 14:01:54 -08:00
Jamie V
e03683e11a remoiving the object to clear the rows 2023-11-09 13:20:05 -08:00
Jamie V
fde676a807 remoiving the object to clear the rows 2023-11-09 13:11:15 -08:00
Jamie V
7e8917c959 using the actual domainObject 2023-11-09 12:54:03 -08:00
Jamie V
b0aa36b0e3 fixing typo 2023-11-08 16:26:28 -08:00
Jamie V
112ac74cfb adding nextPage 2023-11-08 16:03:57 -08:00
Jamie V
635c725573 initial commit 2023-11-08 13:55:20 -08:00
Michael Rogers
a0fd1f0171 Removed errant brace in ObjectAPI Error (#7192)
Removed errant brace
2023-10-31 07:28:20 -07:00
dependabot[bot]
c7fd584b58 chore(deps-dev): bump @braintree/sanitize-url from 6.0.2 to 6.0.4 (#7190)
Bumps [@braintree/sanitize-url](https://github.com/braintree/sanitize-url) from 6.0.2 to 6.0.4.
- [Changelog](https://github.com/braintree/sanitize-url/blob/main/CHANGELOG.md)
- [Commits](https://github.com/braintree/sanitize-url/compare/v6.0.2...v6.0.4)

---
updated-dependencies:
- dependency-name: "@braintree/sanitize-url"
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-30 23:05:33 +00:00
dependabot[bot]
16ca994cfa chore(deps-dev): bump sinon from 15.1.0 to 17.0.0 (#7155)
Bumps [sinon](https://github.com/sinonjs/sinon) from 15.1.0 to 17.0.0.
- [Release notes](https://github.com/sinonjs/sinon/releases)
- [Changelog](https://github.com/sinonjs/sinon/blob/main/docs/changelog.md)
- [Commits](https://github.com/sinonjs/sinon/compare/v15.1.0...v17.0.0)

---
updated-dependencies:
- dependency-name: sinon
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-29 09:13:09 -07:00
dependabot[bot]
ebe5323f82 chore(deps-dev): bump painterro from 1.2.78 to 1.2.87 (#7165)
Bumps [painterro](https://github.com/devforth/painterro) from 1.2.78 to 1.2.87.
- [Release notes](https://github.com/devforth/painterro/releases)
- [Changelog](https://github.com/devforth/painterro/blob/master/Release.md)
- [Commits](https://github.com/devforth/painterro/compare/v1.2.78...v1.2.87)

---
updated-dependencies:
- dependency-name: painterro
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-29 15:55:57 +00:00
dependabot[bot]
7a8a6d3649 chore(deps-dev): bump eslint-plugin-unicorn from 44.0.2 to 48.0.1 (#7163)
Bumps [eslint-plugin-unicorn](https://github.com/sindresorhus/eslint-plugin-unicorn) from 44.0.2 to 48.0.1.
- [Release notes](https://github.com/sindresorhus/eslint-plugin-unicorn/releases)
- [Commits](https://github.com/sindresorhus/eslint-plugin-unicorn/compare/v44.0.2...v48.0.1)

---
updated-dependencies:
- dependency-name: eslint-plugin-unicorn
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-29 06:55:09 -07:00
dependabot[bot]
25e7a16c77 chore(deps-dev): bump cspell from 7.3.6 to 7.3.8 (#7162)
Bumps [cspell](https://github.com/streetsidesoftware/cspell) from 7.3.6 to 7.3.8.
- [Release notes](https://github.com/streetsidesoftware/cspell/releases)
- [Changelog](https://github.com/streetsidesoftware/cspell/blob/main/CHANGELOG.md)
- [Commits](https://github.com/streetsidesoftware/cspell/compare/v7.3.6...v7.3.8)

---
updated-dependencies:
- dependency-name: cspell
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-28 14:57:47 +00:00
dependabot[bot]
141939295a chore(deps): bump actions/setup-node from 3 to 4 (#7166)
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 4.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](https://github.com/actions/setup-node/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
2023-10-24 16:52:17 -07:00
dependabot[bot]
2c1040c7c0 chore(deps-dev): bump sass from 1.63.4 to 1.68.0 (#7086)
Bumps [sass](https://github.com/sass/dart-sass) from 1.63.4 to 1.68.0.
- [Release notes](https://github.com/sass/dart-sass/releases)
- [Changelog](https://github.com/sass/dart-sass/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sass/dart-sass/compare/1.63.4...1.68.0)

---
updated-dependencies:
- dependency-name: sass
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Rukmini Bose (Ruki) <48999852+rukmini-bose@users.noreply.github.com>
2023-10-24 16:26:27 -07:00
Jamie V
d94fe8806b [Plots] Gracefully handle Float32Array breaking values (#7138)
* WIP

* guaranteeing float32breaking values for swgs when option is set

* cleaning up and clarity

* more clarity

* removing randomization of float breaking number, as it is not necessary

* logging the values that could not be plotted for awareness

* remving auto-added imports

---------

Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
2023-10-24 23:07:43 +00:00
Jamie V
7bf983210c [Filters] Fix view based filters when string input is enabled (#7050)
* de-reactifying some objects for clarity, handling strings for filters, some vue 3 formatting

* removing debug, fixing string value persistence

* remove unnecessary change

* removing vue utils from non vue files

* nipping proxy objects in the bud

* linting

---------

Co-authored-by: Jesse Mazzella <ozyx@users.noreply.github.com>
2023-10-24 15:33:08 -07:00
Khalid Adil
8f92cd4206 [Tooltips] Finish tests for gauges, telemetry tables, recently viewed items, and time strips (#7145)
Finish tests for gauge, telemetry tables, recently viewed items, and time strips

Co-authored-by: David Tsay <3614296+davetsay@users.noreply.github.com>
2023-10-24 22:06:40 +00:00
Scott Bell
13311b9fc8 Prevent infinite loop when updating a table row in place (#7154)
* bump index on update row in place

* add test

* Removing problematic test

* spelling
2023-10-23 09:22:13 -07:00
Jesse Mazzella
2daec448da chore: bump version to 3.2.0-next (#7117)
chore: bump version to 3.2.0-next

Co-authored-by: Scott Bell <scott@traclabs.com>
2023-10-23 12:23:34 +02:00
dependabot[bot]
5bd8d17592 chore(deps-dev): bump jasmine-core from 5.0.0 to 5.1.1 (#7008)
Bumps [jasmine-core](https://github.com/jasmine/jasmine) from 5.0.0 to 5.1.1.
- [Release notes](https://github.com/jasmine/jasmine/releases)
- [Changelog](https://github.com/jasmine/jasmine/blob/main/RELEASE.md)
- [Commits](https://github.com/jasmine/jasmine/compare/v5.0.0...v5.1.1)

---
updated-dependencies:
- dependency-name: jasmine-core
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-20 23:20:32 +00:00
dependabot[bot]
954c72b100 chore(deps-dev): bump eslint-plugin-vue from 9.15.0 to 9.17.0 (#6907)
Bumps [eslint-plugin-vue](https://github.com/vuejs/eslint-plugin-vue) from 9.15.0 to 9.17.0.
- [Release notes](https://github.com/vuejs/eslint-plugin-vue/releases)
- [Commits](https://github.com/vuejs/eslint-plugin-vue/compare/v9.15.0...v9.17.0)

---
updated-dependencies:
- dependency-name: eslint-plugin-vue
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-20 19:01:12 +00:00
Jesse Mazzella
43338f3980 chore: remove vue/compat and complete Vue 3 migration (#7133)
* chore: remove custom `compatConfig` settings

* chore: remove `vue-compat` and adjust webpack config

* chore: explicitly define Vue feature flags

* fix: `_data` property moved to `_.data`

* fix(e2e): revert to original test procedures

* refactor: replace final instances of `$set`

* refactor: remove `Vue` imports from tests

* refactor: `Vue.ref()` -> `ref()`

* refactor: actually push the changes...

* test: replace unit test with e2e test

* test: remove test as it's already covered by e2e

* fix(test): use `$ref`s instead of `$children`

* test(fix): more `$refs`

* fix(test): more `$refs`

* fix(test): use `$refs` in InspectorStyles tests

* fix(SearchComponent): use `$attrs` correctly

---------

Co-authored-by: Scott Bell <scott@traclabs.com>
2023-10-19 09:08:39 -07:00
dependabot[bot]
1414f54c17 chore(deps-dev): bump vue-eslint-parser from 9.3.1 to 9.3.2 (#7125)
Bumps [vue-eslint-parser](https://github.com/vuejs/vue-eslint-parser) from 9.3.1 to 9.3.2.
- [Release notes](https://github.com/vuejs/vue-eslint-parser/releases)
- [Commits](https://github.com/vuejs/vue-eslint-parser/compare/v9.3.1...v9.3.2)

---
updated-dependencies:
- dependency-name: vue-eslint-parser
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-18 15:49:29 +00:00
Jesse Mazzella
9849e0398e fix(#7143): add eslint-plugin-no-sanitize and fix errors (#7144) 2023-10-16 09:26:12 -07:00
David Tsay
76889cf60d Rename all configuration inspector tabs to Config (#7140) 2023-10-12 13:48:13 -07:00
Scott Bell
26d3bd1e69 When dropping an unsupported file onto a notebook entry, tell the user it isnt supported (#7115)
* handle unknown files and deal with copy/paste

* add some nice errors if couch pukes

* added how to adjust couchdb limits

* throw error on anntotation change

* keep blockquotes

* add test for blockquotes

* allow multi-file drop of images too

* add test for big files

* spell check

* check for null

* need to ignore console errors

* reorder tests so we can ignore console errors

* when creating new entry, ready it for editing

* fix tests and empty embeds

* fix tests

* found similar issue from notebooks in plots
2023-10-12 07:34:32 +02:00
David Tsay
a16a1d35b6 do not store state in singleton action (#7121)
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2023-10-10 15:49:45 -07:00
David 'Epper' Marshall
97b2ebc0bb Fix remaining vue-compat warnings (#6966)
* PascalCase files

* emit warnings

* minor updates

* merge conflict resolve pt 1

* part 2

* update to eventbus

* eventbus spelling

* fix: import

* fix: eventBus injection

* fix: import

* fix(test): provide eventBus in overlay plot tests

* refactor: EventBus as composable

* chore: lint:fix

* chore: require vue event hyphenation

* fix: revert event renames

* refactor: use PascalCase name

* fix: ensure `$attrs` are properly bound

* fix: emit `click` event from SearchComponent

* chore: remove rules already included in `vue/vue3-recommended` ruleset

* fix: remove `Vue` import

* chore: remove unused files

* fix: fix lint scripts and make them cross-platform

* refactor: rename `DataImagery.vue` -> `ImageryInspectorView.vue`

* refactor: rename `NumericData.vue` -> `NumericDataInspectorView.vue`

* refactor: rename components

* refactor: rename `GeneralIndicators.vue` -> `StatusIndicators.vue`

* refactor: rename components

---------

Co-authored-by: Jesse Mazzella <jesse.d.mazzella@nasa.gov>
2023-10-10 13:29:01 -07:00
Khalid Adil
6b32c63039 [Staleness] Fix issue with object view staleness styles not being reset on clock change (#7122)
Add logic to un/re-subscribe when clock changes to object view
2023-10-06 15:26:05 -07:00
Scott Bell
084784a409 Handle negative height & width in image annotations (#7116)
* add fix

* remove debug code

* add test for unholy rectangles

* make test a bit more forgiving

* address pr review
2023-10-06 19:08:42 +02:00
Khalid Adil
734a8dd592 [Staleness] Fix staleness on clock change (#7088)
* Update staleness mixin
* Fix listeners and add guard
* Add check to make sure staleness only shows for correct clock
* Add guard for time api
* Cleanup the setting of isStale in ObjectView
* Cleanup use of combinedKey on LadTableSet
2023-10-04 13:39:20 -07:00
Jesse Mazzella
5eed5de3bb chore(cspell): use --quiet flag (#7110)
chore(cspell): use `--quiet` flag
2023-10-04 14:47:49 +02:00
266 changed files with 2327 additions and 1668 deletions

View File

@@ -483,7 +483,11 @@
"websockets",
"swgs",
"memlab",
"devmode"
"devmode",
"blockquote",
"blockquotes",
"Blockquote",
"Blockquotes"
],
"dictionaries": ["npm", "softwareTerms", "node", "html", "css", "bash", "en_US"],
"ignorePaths": [

View File

@@ -15,7 +15,8 @@ module.exports = {
'plugin:compat/recommended',
'plugin:vue/vue3-recommended',
'plugin:you-dont-need-lodash-underscore/compatible',
'plugin:prettier/recommended'
'plugin:prettier/recommended',
'plugin:no-unsanitized/DOM'
],
parser: 'vue-eslint-parser',
parserOptions: {
@@ -145,29 +146,26 @@ module.exports = {
'no-implicit-coercion': 'error',
//https://eslint.org/docs/rules/no-unneeded-ternary
'no-unneeded-ternary': 'error',
"unicorn/filename-case": [
"error",
'unicorn/filename-case': [
'error',
{
"cases": {
"pascalCase": true
cases: {
pascalCase: true
},
"ignore": [
"^.*\\.js$"
]
ignore: ['^.*\\.js$']
}
],
'vue/first-attribute-linebreak': 'error',
'vue/multiline-html-element-content-newline': 'off',
'vue/singleline-html-element-content-newline': 'off',
'vue/multi-word-component-names': 'off', // TODO enable, align with conventions
'vue/no-mutating-props': 'off'
'vue/no-mutating-props': 'off' // TODO: Remove this rule and fix resulting errors
},
overrides: [
{
files: LEGACY_FILES,
rules: {
'no-unused-vars': [
'warn',
'error',
{
vars: 'all',
args: 'none',

View File

@@ -16,7 +16,7 @@ jobs:
timeout-minutes: 60
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 'lts/hydrogen'

View File

@@ -21,7 +21,7 @@ jobs:
- windows-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 'lts/hydrogen'

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: lts/hydrogen
- run: npm install
@@ -27,7 +27,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: lts/hydrogen
registry-url: https://registry.npmjs.org/

View File

@@ -32,7 +32,7 @@ jobs:
- uses: actions/checkout@v3
- name: Setup node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node_version }}
architecture: ${{ matrix.architecture }}

View File

@@ -77,8 +77,7 @@ const config = {
MCT: path.join(projectRootDir, 'src/MCT'),
testUtils: path.join(projectRootDir, 'src/utils/testUtils.js'),
objectUtils: path.join(projectRootDir, 'src/api/objects/object-utils.js'),
utils: path.join(projectRootDir, 'src/utils'),
vue: path.join(projectRootDir, 'node_modules/@vue/compat/dist/vue.esm-bundler.js'),
utils: path.join(projectRootDir, 'src/utils')
}
},
plugins: [
@@ -86,7 +85,9 @@ const config = {
__OPENMCT_VERSION__: `'${packageDefinition.version}'`,
__OPENMCT_BUILD_DATE__: `'${new Date()}'`,
__OPENMCT_REVISION__: `'${gitRevision}'`,
__OPENMCT_BUILD_BRANCH__: `'${gitBranch}'`
__OPENMCT_BUILD_BRANCH__: `'${gitBranch}'`,
__VUE_OPTIONS_API__: true, // enable/disable Options API support, default: true
__VUE_PROD_DEVTOOLS__: false // enable/disable devtools support in production, default: false
}),
new VueLoaderPlugin(),
new CopyWebpackPlugin({
@@ -115,7 +116,7 @@ const config = {
new webpack.BannerPlugin({
test: /.*Theme\.css$/,
raw: true,
banner: '@charset "UTF-8";',
banner: '@charset "UTF-8";'
})
],
module: {
@@ -142,10 +143,7 @@ const config = {
options: {
compilerOptions: {
hoistStatic: false,
whitespace: 'preserve',
compatConfig: {
MODE: 2
}
whitespace: 'preserve'
}
}
},

View File

@@ -34,7 +34,6 @@ async function enterTextEntry(page, text) {
await page.locator(NOTEBOOK_DROP_AREA).click();
// enter text
await page.getByLabel('Notebook Entry Display').last().click();
await page.getByLabel('Notebook Entry Input').last().fill(text);
await commitEntry(page);
}
@@ -53,6 +52,7 @@ async function dragAndDropEmbed(page, notebookObject) {
await page.click('button[title="Show selected item in tree"]');
// Drag and drop the SWG into the notebook
await page.dragAndDrop(`text=${swg.name}`, NOTEBOOK_DROP_AREA);
await commitEntry(page);
}
/**

View File

@@ -0,0 +1,59 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2023, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*
Verify that the "Clear Data" menu action performs as expected for various object types.
*/
const { test, expect } = require('../../pluginFixtures.js');
const { createDomainObjectWithDefaults } = require('../../appActions.js');
const backgroundImageSelector = '.c-imagery__main-image__background-image';
test.describe('Clear Data Action', () => {
test.beforeEach(async ({ page }) => {
// Go to baseURL
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create a default 'Example Imagery' object
const exampleImagery = await createDomainObjectWithDefaults(page, { type: 'Example Imagery' });
// Verify that the created object is focused
await expect(page.locator('.l-browse-bar__object-name')).toContainText(exampleImagery.name);
await page.locator('.c-imagery__main-image__bg').hover({ trial: true });
await expect(page.locator(backgroundImageSelector)).toBeVisible();
});
test('works as expected with Example Imagery', async ({ page }) => {
await expect(await page.locator('.c-thumb__image').count()).toBeGreaterThan(0);
// Click the "Clear Data" menu action
await page.getByTitle('More options').click();
const clearDataMenuItem = page.getByRole('menuitem', {
name: 'Clear Data'
});
await expect(clearDataMenuItem).toBeEnabled();
await clearDataMenuItem.click();
// Verify that the background image is no longer visible
await expect(page.locator(backgroundImageSelector)).toBeHidden();
await expect(await page.locator('.c-thumb__image').count()).toBe(0);
});
});

View File

@@ -40,7 +40,7 @@ test.describe('The Fault Management Plugin using example faults', () => {
}) => {
await utils.selectFaultItem(page, 1);
await page.getByRole('tab', { name: 'Fault Management Configuration' }).click();
await page.getByRole('tab', { name: 'Config' }).click();
const selectedFaultName = await page
.locator('.c-fault-mgmt__list.is-selected .c-fault-mgmt__list-faultname')
.textContent();
@@ -65,7 +65,7 @@ test.describe('The Fault Management Plugin using example faults', () => {
);
expect.soft(await selectedRows.count()).toEqual(2);
await page.getByRole('tab', { name: 'Fault Management Configuration' }).click();
await page.getByRole('tab', { name: 'Config' }).click();
const firstSelectedFaultName = await selectedRows.nth(0).textContent();
const secondSelectedFaultName = await selectedRows.nth(1).textContent();
const firstNameInInspectorCount = await page

View File

@@ -209,7 +209,6 @@ test.describe('Example Imagery Object', () => {
const canvasBoundingBox = await canvas.boundingBox();
const canvasCenterX = canvasBoundingBox.x + canvasBoundingBox.width / 2;
const canvasCenterY = canvasBoundingBox.y + canvasBoundingBox.height / 2;
await Promise.all(tagHotkey.map((x) => page.keyboard.down(x)));
await page.mouse.down();
// steps not working for me here
@@ -222,7 +221,7 @@ test.describe('Example Imagery Object', () => {
await expect(page.locator('[role="toolbar"][aria-label="Image controls"]')).toBeVisible();
await Promise.all(tagHotkey.map((x) => page.keyboard.up(x)));
//Wait for canvas to stabilize.
// Wait for canvas to stabilize.
await canvas.hover({ trial: true });
// add some tags
@@ -234,6 +233,20 @@ test.describe('Example Imagery Object', () => {
await page.getByRole('button', { name: /Add Tag/ }).click();
await page.getByPlaceholder('Type to select tag').click();
await page.getByText('Science').click();
// click on a separate part of the canvas to ensure no tags appear
await page.mouse.click(canvasCenterX + 10, canvasCenterY + 10);
await expect(page.getByText('Driving')).toBeHidden();
await expect(page.getByText('Science')).toBeHidden();
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/nasa/openmct/issues/7083'
});
// click on annotation again and expect tags to appear
await page.mouse.click(canvasCenterX - 50, canvasCenterY - 50);
await expect(page.getByText('Driving')).toBeVisible();
await expect(page.getByText('Science')).toBeVisible();
});
test('Can use + - buttons to zoom on the image @unstable', async ({ page }) => {

View File

@@ -279,7 +279,7 @@ test.describe('Notebook entry tests', () => {
// Click .c-notebook__drag-area
await page.locator('.c-notebook__drag-area').click();
await expect(page.getByLabel('Notebook Entry Display')).toBeVisible();
await expect(page.getByLabel('Notebook Entry Input')).toBeVisible();
await expect(page.getByLabel('Notebook Entry', { exact: true })).toHaveClass(/is-selected/);
});
test('When an object is dropped into a notebook, a new entry is created and it should be focused @unstable', async ({
@@ -514,10 +514,23 @@ test.describe('Notebook entry tests', () => {
const childItem = page.locator('li:has-text("List Item 2") ol li:has-text("Order 2")');
await expect(childItem).toBeVisible();
// Blocks
const blockTest = '```javascript\nconst foo = "bar";\nconst bar = "foo";\n```';
await nbUtils.enterTextEntry(page, blockTest);
// Code Blocks
const codeblockTest = '```javascript\nconst foo = "bar";\nconst bar = "foo";\n```';
await nbUtils.enterTextEntry(page, codeblockTest);
const codeBlock = page.locator('code.language-javascript:has-text("const foo = \\"bar\\";")');
await expect(codeBlock).toBeVisible();
// Blockquotes
const blockquoteTest =
'This is a quote by Mark Twain:\n> "The man with a new idea is a crank\n>until the idea succeeds."';
await nbUtils.enterTextEntry(page, blockquoteTest);
const firstLineOfBlockquoteText = page.locator(
'blockquote:has-text("The man with a new idea is a crank")'
);
await expect(firstLineOfBlockquoteText).toBeVisible();
const secondLineOfBlockquoteText = page.locator(
'blockquote:has-text("until the idea succeeds")'
);
await expect(secondLineOfBlockquoteText).toBeVisible();
});
});

View File

@@ -188,12 +188,11 @@ test.describe('Snapshot image tests', () => {
}, fileData);
await page.dispatchEvent('.c-notebook__drag-area', 'drop', { dataTransfer: dropTransfer });
await page.locator('.c-ne__save-button > button').click();
// be sure that entry was created
await expect(page.getByText('favicon-96x96.png')).toBeVisible();
await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).click();
// expect large image to be displayed
await expect(page.getByRole('dialog').getByText('favicon-96x96.png')).toBeVisible();
@@ -215,3 +214,59 @@ test.describe('Snapshot image tests', () => {
expect(await page.getByRole('img', { name: 'favicon-96x96.png thumbnail' }).count()).toBe(1);
});
});
test.describe('Snapshot image failure tests', () => {
test.use({ failOnConsoleError: false });
test.beforeEach(async ({ page }) => {
//Navigate to baseURL
await page.goto('./', { waitUntil: 'domcontentloaded' });
// Create Notebook
await createDomainObjectWithDefaults(page, {
type: NOTEBOOK_NAME
});
});
test('Get an error notification when dropping unknown file onto notebook entry', async ({
page
}) => {
// fill Uint8Array array with some garbage data
const garbageData = new Uint8Array(100);
const fileData = Array.from(garbageData);
const dropTransfer = await page.evaluateHandle((data) => {
const dataTransfer = new DataTransfer();
const file = new File([new Uint8Array(data)], 'someGarbage.foo', { type: 'unknown/garbage' });
dataTransfer.items.add(file);
return dataTransfer;
}, fileData);
await page.dispatchEvent('.c-notebook__drag-area', 'drop', { dataTransfer: dropTransfer });
// should have gotten a notification from OpenMCT that we couldn't add it
await expect(page.getByText('Unknown object(s) dropped and cannot embed')).toBeVisible();
});
test('Get an error notification when dropping big files onto notebook entry', async ({
page
}) => {
const garbageSize = 15 * 1024 * 1024; // 15 megabytes
await page.addScriptTag({
// make the garbage client side
content: `window.bigGarbageData = new Uint8Array(${garbageSize})`
});
const bigDropTransfer = await page.evaluateHandle(() => {
const dataTransfer = new DataTransfer();
const file = new File([window.bigGarbageData], 'bigBoy.png', { type: 'image/png' });
dataTransfer.items.add(file);
return dataTransfer;
});
await page.dispatchEvent('.c-notebook__drag-area', 'drop', { dataTransfer: bigDropTransfer });
// should have gotten a notification from OpenMCT that we couldn't add it as it's too big
await expect(page.getByText('unable to embed')).toBeVisible();
});
});

View File

@@ -150,7 +150,6 @@ test.describe('Tagging in Notebooks @addInit', () => {
await createNotebookEntryAndTags(page);
await page.locator('text=To start a new entry, click here or drag and drop any object').click();
await page.getByLabel('Notebook Entry Display').last().click();
await page.getByLabel('Notebook Entry Input').fill(`An entry without tags`);
await page.locator('.c-ne__save-button > button').click();

View File

@@ -77,11 +77,11 @@ test.describe('Grand Search', () => {
// Click [aria-label="OpenMCT Search"] a >> nth=0
await page.locator('[aria-label="Search Result"] >> nth=0').click();
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeInViewport();
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
// Fill [aria-label="OpenMCT Search"] input[type="search"]
await page.locator('[aria-label="OpenMCT Search"] input[type="search"]').fill('foo');
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).not.toBeInViewport();
await expect(page.locator('[aria-label="Search Result"] >> nth=0')).toBeHidden();
// Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1
await page

View File

@@ -89,20 +89,6 @@ test.describe('Verify tooltips', () => {
await expandEntireTree(page);
});
// LAD Tables - DONE
// Expanded collapsed plot legend - DONE
// Object Labels - DONE
// Display Layout headers - DONE
// Flexible Layout headers - DONE
// Tab View layout headers - DONE
// Search - DONE
// Gauge -
// Notebook Embed - DONE
// Telemetry Table -
// Timeline Objects
// Tree - DONE
// Recent Objects
test('display correct paths for LAD tables', async ({ page, openmctConfig }) => {
// Create LAD table
await createDomainObjectWithDefaults(page, {
@@ -254,13 +240,13 @@ test.describe('Verify tooltips', () => {
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe('My Items / Test Overlay Plot');
// await page.keyboard.up('Control');
// await page.locator('.c-plot-legend__view-control >> nth=0').click();
// await page.keyboard.down('Control');
// await page.locator('.plot-wrapper-expanded-legend .plot-series-name').first().hover();
// tooltipText = await page.locator('.c-tooltip').textContent();
// tooltipText = tooltipText.replace('\n', '').trim();
// expect(tooltipText).toBe(sineWaveObject1.path);
await page.keyboard.up('Control');
await page.locator('.c-plot-legend__view-control >> nth=0').click();
await page.keyboard.down('Control');
await page.locator('.plot-wrapper-expanded-legend .plot-series-name').first().hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject1.path);
await page.getByText('Test Stacked Plot').nth(2).hover();
tooltipText = await page.locator('.c-tooltip').textContent();
@@ -345,18 +331,18 @@ test.describe('Verify tooltips', () => {
expect(tooltipText).toBe(sineWaveObject3.path);
});
test('display path for source telemetry when hovering over gauge', ({ page }) => {
expect(true).toBe(true);
// await createDomainObjectWithDefaults(page, {
// type: 'Gauge',
// name: 'Test Gauge'
// });
// await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-gauge__wrapper');
// await page.keyboard.down('Control');
// await page.locator('.c-gauge__current-value-text-wrapper').hover();
// let tooltipText = await page.locator('.c-tooltip').textContent();
// tooltipText = tooltipText.replace('\n', '').trim();
// expect(tooltipText).toBe(sineWaveObject3.path);
test('display path for source telemetry when hovering over gauge', async ({ page }) => {
await createDomainObjectWithDefaults(page, {
type: 'Gauge',
name: 'Test Gauge'
});
await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-gauge__wrapper');
await page.keyboard.down('Control');
// eslint-disable-next-line playwright/no-force-option
await page.locator('.c-gauge.c-dial').hover({ position: { x: 0, y: 0 }, force: true });
let tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject3.path);
});
test('display tooltip path for notebook embeds', async ({ page }) => {
@@ -373,26 +359,105 @@ test.describe('Verify tooltips', () => {
expect(tooltipText).toBe(sineWaveObject3.path);
});
// test('display tooltip path for telemetry table names', async ({ page }) => {
// await setEndOffset(page, { secs: '10' });
// await createDomainObjectWithDefaults(page, {
// type: 'Telemetry Table',
// name: 'Test Telemetry Table'
// });
test('display tooltip path for telemetry table names', async ({ page }) => {
// set endBound to 10 seconds after start bound
const url = await page.url();
const parsedUrl = new URL(url.replace('#', '!'));
const startBound = Number(parsedUrl.searchParams.get('tc.startBound'));
const tenSecondsInMilliseconds = 10 * 1000;
const endBound = startBound + tenSecondsInMilliseconds;
parsedUrl.searchParams.set('tc.endBound', endBound);
await page.goto(parsedUrl.href.replace('!', '#'));
// await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.c-telemetry-table');
// await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-telemetry-table');
await createDomainObjectWithDefaults(page, {
type: 'Telemetry Table',
name: 'Test Telemetry Table'
});
// await page.locator('button[title="Save"]').click();
// await page.locator('text=Save and Finish Editing').click();
await page.dragAndDrop(`text=${sineWaveObject1.name}`, '.c-telemetry-table');
await page.dragAndDrop(`text=${sineWaveObject3.name}`, '.c-telemetry-table');
// // .c-telemetry-table__body
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
await page.keyboard.down('Control');
// await page.keyboard.down('Control');
await page.locator('.noselect > [title="SWG 3"]').first().hover();
let tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject3.path);
// await page.locator('.noselect > [title="SWG 3"]').first().hover();
// let tooltipText = await page.locator('.c-tooltip').textContent();
// tooltipText = tooltipText.replace('\n', '').trim();
// expect(tooltipText).toBe(sineWaveObject3.path);
// });
await page.locator('.noselect > [title="SWG 1"]').first().hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject1.path);
});
test('display tooltip path for recently viewed items', async ({ page }) => {
// drag up Recently Viewed pane
await page
.locator('.l-pane.l-pane--vertical-handle-before', {
hasText: 'Recently Viewed'
})
.locator('.l-pane__handle')
.hover();
await page.mouse.down();
await page.mouse.move(0, 300);
await page.mouse.up();
await page.keyboard.down('Control');
await page.getByLabel('Recent Objects').getByText(sineWaveObject3.name).hover();
let tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject3.path);
await page.getByLabel('Recent Objects').getByText(sineWaveObject2.name).hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject2.path);
await page.getByLabel('Recent Objects').getByText(sineWaveObject1.name).hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject1.path);
});
test('display tooltip path for time strips', async ({ page }) => {
// Create Time Strip
await createDomainObjectWithDefaults(page, {
type: 'Time Strip',
name: 'Test Time Strip'
});
// Edit Overlay Plot
await page.locator('[title="Edit"]').click();
await page.dragAndDrop(
`text=${sineWaveObject1.name}`,
'.c-object-view.is-object-type-time-strip'
);
await page.dragAndDrop(
`text=${sineWaveObject2.name}`,
'.c-object-view.is-object-type-time-strip'
);
await page.dragAndDrop(
`text=${sineWaveObject3.name}`,
'.c-object-view.is-object-type-time-strip'
);
await page.locator('button[title="Save"]').click();
await page.locator('text=Save and Finish Editing').click();
await page.keyboard.down('Control');
await page.getByText(sineWaveObject1.name).nth(2).hover();
let tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject1.path);
await page.getByText(sineWaveObject2.name).nth(2).hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject2.path);
await page.getByText(sineWaveObject3.name).nth(2).hover();
tooltipText = await page.locator('.c-tooltip').textContent();
tooltipText = tooltipText.replace('\n', '').trim();
expect(tooltipText).toBe(sineWaveObject3.path);
});
});

View File

@@ -131,7 +131,6 @@ test.describe('Performance tests', () => {
await page.evaluate(() => window.performance.mark('new-notebook-entry-created'));
// Enter Notebook Entry text
await page.getByLabel('Notebook Entry').last().click();
await page.getByLabel('Notebook Entry Input').last().fill('New Entry');
await page.locator('.c-ne__save-button').click();
await page.evaluate(() => window.performance.mark('new-notebook-entry-filled'));

View File

@@ -29,7 +29,8 @@ define(['./WorkerInterface'], function (WorkerInterface) {
randomness: 0,
phase: 0,
loadDelay: 0,
infinityValues: false
infinityValues: false,
exceedFloat32: false
};
function GeneratorProvider(openmct, StalenessProvider) {
@@ -53,7 +54,8 @@ define(['./WorkerInterface'], function (WorkerInterface) {
'randomness',
'phase',
'loadDelay',
'infinityValues'
'infinityValues',
'exceedFloat32'
];
request = request || {};

View File

@@ -85,7 +85,8 @@
data.offset,
data.phase,
data.randomness,
data.infinityValues
data.infinityValues,
data.exceedFloat32
),
wavelengths: wavelengths(),
intensities: intensities(),
@@ -96,7 +97,8 @@
data.offset,
data.phase,
data.randomness,
data.infinityValues
data.infinityValues,
data.exceedFloat32
)
}
});
@@ -136,6 +138,7 @@
var randomness = request.randomness;
var loadDelay = Math.max(request.loadDelay, 0);
var infinityValues = request.infinityValues;
var exceedFloat32 = request.exceedFloat32;
var step = 1000 / dataRateInHz;
var nextStep = start - (start % step) + step;
@@ -146,10 +149,28 @@
data.push({
utc: nextStep,
yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, period, amplitude, offset, phase, randomness, infinityValues),
sin: sin(
nextStep,
period,
amplitude,
offset,
phase,
randomness,
infinityValues,
exceedFloat32
),
wavelengths: wavelengths(),
intensities: intensities(),
cos: cos(nextStep, period, amplitude, offset, phase, randomness, infinityValues)
cos: cos(
nextStep,
period,
amplitude,
offset,
phase,
randomness,
infinityValues,
exceedFloat32
)
});
}
@@ -176,9 +197,26 @@
});
}
function cos(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
if (infinityValues && Math.random() > 0.5) {
function cos(
timestamp,
period,
amplitude,
offset,
phase,
randomness,
infinityValues,
exceedFloat32
) {
if (infinityValues && exceedFloat32) {
if (Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
} else if (Math.random() < 0.01) {
return getRandomFloat32OverflowValue();
}
} else if (infinityValues && Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
} else if (exceedFloat32 && Math.random() < 0.01) {
return getRandomFloat32OverflowValue();
}
return (
@@ -188,9 +226,26 @@
);
}
function sin(timestamp, period, amplitude, offset, phase, randomness, infinityValues) {
if (infinityValues && Math.random() > 0.5) {
function sin(
timestamp,
period,
amplitude,
offset,
phase,
randomness,
infinityValues,
exceedFloat32
) {
if (infinityValues && exceedFloat32) {
if (Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
} else if (Math.random() < 0.01) {
return getRandomFloat32OverflowValue();
}
} else if (infinityValues && Math.random() > 0.5) {
return Number.POSITIVE_INFINITY;
} else if (exceedFloat32 && Math.random() < 0.01) {
return getRandomFloat32OverflowValue();
}
return (
@@ -200,6 +255,13 @@
);
}
// Values exceeding float32 range (Positive: 3.4+38, Negative: -3.4+38)
function getRandomFloat32OverflowValue() {
const sign = Math.random() > 0.5 ? 1 : -1;
return sign * 3.4e39;
}
function wavelengths() {
let values = [];
while (values.length < 5) {

View File

@@ -122,6 +122,13 @@ export default function (openmct) {
key: 'infinityValues',
property: ['telemetry', 'infinityValues']
},
{
name: 'Exceed Float32 Limits',
control: 'toggleSwitch',
cssClass: 'l-input',
key: 'exceedFloat32',
property: ['telemetry', 'exceedFloat32']
},
{
name: 'Provide Staleness Updates',
control: 'toggleSwitch',
@@ -140,6 +147,7 @@ export default function (openmct) {
randomness: 0,
loadDelay: 0,
infinityValues: false,
exceedFloat32: false,
staleness: false
};
}

View File

@@ -1,19 +0,0 @@
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!'
};
}
};
</script>
<style>
.example {
color: red;
}
</style>

View File

@@ -1,36 +0,0 @@
import Vue from 'vue';
import HelloWorld from './HelloWorld.vue';
function SimpleVuePlugin() {
return function install(openmct) {
openmct.types.addType('hello-world', {
name: 'Hello World',
description: 'An introduction object',
creatable: true
});
openmct.objectViews.addProvider({
name: 'demo-provider',
key: 'hello-world',
cssClass: 'icon-packet',
canView: function (d) {
return d.type === 'hello-world';
},
view: function (domainObject) {
var vm;
return {
show: function (container) {
vm = new Vue(HelloWorld);
container.appendChild(vm.$mount().$el);
},
destroy: function (container) {
//vm.$destroy();
}
};
}
});
};
}
export default SimpleVuePlugin;

View File

@@ -1,10 +1,10 @@
{
"name": "openmct",
"version": "3.1.0-next",
"version": "3.2.0-next",
"description": "The Open MCT core platform",
"devDependencies": {
"@babel/eslint-parser": "7.22.5",
"@braintree/sanitize-url": "6.0.2",
"@braintree/sanitize-url": "6.0.4",
"@deploysentinel/playwright": "0.3.4",
"@percy/cli": "1.26.0",
"@percy/playwright": "1.0.4",
@@ -12,14 +12,13 @@
"@types/eventemitter3": "1.2.0",
"@types/jasmine": "4.3.4",
"@types/lodash": "4.14.192",
"@vue/compat": "3.3.4",
"@vue/compiler-sfc": "3.3.4",
"babel-loader": "9.1.0",
"babel-plugin-istanbul": "6.1.1",
"codecov": "3.8.3",
"comma-separated-values": "3.6.4",
"copy-webpack-plugin": "11.0.0",
"cspell": "7.3.6",
"cspell": "7.3.8",
"css-loader": "6.8.1",
"d3-axis": "3.0.0",
"d3-scale": "3.3.0",
@@ -27,11 +26,12 @@
"eslint": "8.48.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-compat": "4.2.0",
"eslint-plugin-no-unsanitized": "4.0.2",
"eslint-plugin-playwright": "0.12.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-simple-import-sort": "10.0.0",
"eslint-plugin-unicorn": "44.0.2",
"eslint-plugin-vue": "9.15.0",
"eslint-plugin-unicorn": "48.0.1",
"eslint-plugin-vue": "9.17.0",
"eslint-plugin-you-dont-need-lodash-underscore": "6.12.0",
"eventemitter3": "1.2.0",
"file-saver": "2.0.5",
@@ -39,7 +39,7 @@
"git-rev-sync": "3.0.2",
"html2canvas": "1.4.1",
"imports-loader": "4.0.1",
"jasmine-core": "5.0.0",
"jasmine-core": "5.1.1",
"karma": "6.4.2",
"karma-chrome-launcher": "3.2.0",
"karma-cli": "2.0.0",
@@ -59,21 +59,22 @@
"moment-timezone": "0.5.41",
"npm-run-all2": "6.0.6",
"nyc": "15.1.0",
"painterro": "1.2.78",
"painterro": "1.2.87",
"plotly.js-basic-dist": "2.20.0",
"plotly.js-gl2d-dist": "2.20.0",
"prettier": "2.8.7",
"printj": "1.3.1",
"resolve-url-loader": "5.0.0",
"sanitize-html": "2.11.0",
"sass": "1.63.4",
"sass": "1.68.0",
"sass-loader": "13.3.2",
"sinon": "15.1.0",
"sinon": "17.0.0",
"style-loader": "3.3.3",
"tiny-emitter": "2.1.0",
"typescript": "5.2.2",
"uuid": "9.0.0",
"vue": "3.3.4",
"vue-eslint-parser": "9.3.1",
"vue-eslint-parser": "9.3.2",
"vue-loader": "16.8.3",
"webpack": "5.88.0",
"webpack-cli": "5.1.1",
@@ -85,9 +86,9 @@
"start": "npx webpack serve --config ./.webpack/webpack.dev.js",
"start:prod": "npx webpack serve --config ./.webpack/webpack.prod.js",
"start:coverage": "npx webpack serve --config ./.webpack/webpack.coverage.js",
"lint:js": "eslint example src e2e --ext .js openmct.js --max-warnings=0",
"lint:vue": "eslint example src --ext .vue",
"lint:spelling": "cspell \"**/*.{js,md,vue}\" --show-context --gitignore",
"lint:js": "eslint \"example/**/*.js\" \"src/**/*.js\" \"e2e/**/*.js\" \"openmct.js\" --max-warnings=0",
"lint:vue": "eslint \"src/**/*.vue\"",
"lint:spelling": "cspell \"**/*.{js,md,vue}\" --show-context --gitignore --quiet",
"lint": "run-p \"lint:js -- {1}\" \"lint:vue -- {1}\" \"lint:spelling -- {1}\" --",
"lint:fix": "eslint example src e2e --ext .js,.vue openmct.js --fix",
"build:prod": "webpack --config ./.webpack/webpack.prod.js",

View File

@@ -33,7 +33,7 @@ define([
'./ui/registries/ToolbarRegistry',
'./ui/router/ApplicationRouter',
'./ui/router/Browse',
'./ui/layout/Layout.vue',
'./ui/layout/AppLayout.vue',
'./ui/preview/plugin',
'./api/Branding',
'./plugins/licenses/plugin',

View File

@@ -3,9 +3,9 @@ import mount from 'utils/mount';
import AutoCompleteField from './components/controls/AutoCompleteField.vue';
import CheckBoxField from './components/controls/CheckBoxField.vue';
import ClockDisplayFormatField from './components/controls/ClockDisplayFormatField.vue';
import Datetime from './components/controls/Datetime.vue';
import Datetime from './components/controls/DatetimeField.vue';
import FileInput from './components/controls/FileInput.vue';
import Locator from './components/controls/Locator.vue';
import Locator from './components/controls/LocatorField.vue';
import NumberField from './components/controls/NumberField.vue';
import SelectField from './components/controls/SelectField.vue';
import TextAreaField from './components/controls/TextAreaField.vue';
@@ -87,7 +87,7 @@ export default class FormControl {
onChange
};
},
template: `<FormControlComponent :model="model" @onChange="onChange"></FormControlComponent>`
template: `<FormControlComponent :model="model" @on-change="onChange"></FormControlComponent>`
},
{
element,

View File

@@ -171,7 +171,7 @@ export default class FormsAPI {
};
},
template:
'<FormProperties :model="formStructure" @onChange="onChange" @onCancel="onCancel" @onSave="onSave"></FormProperties>'
'<FormProperties :model="formStructure" @on-change="onChange" @on-cancel="onCancel" @on-save="onSave"></FormProperties>'
},
{
element,

View File

@@ -44,7 +44,7 @@
:css-class="row.cssClass"
:first="index < 1"
:row="row"
@onChange="onChange"
@on-change="onChange"
/>
</div>
</form>
@@ -94,6 +94,7 @@ export default {
}
}
},
emits: ['on-change', 'on-save', 'on-cancel'],
data() {
return {
invalidProperties: {},
@@ -144,13 +145,13 @@ export default {
onChange(data) {
this.invalidProperties[data.model.key] = data.invalid;
this.$emit('onChange', data);
this.$emit('on-change', data);
},
onCancel() {
this.$emit('onCancel');
this.$emit('on-cancel');
},
onSave() {
this.$emit('onSave');
this.$emit('on-save');
}
}
};

View File

@@ -21,7 +21,7 @@
-->
<template>
<div class="form-row c-form__row" :class="[{ first: first }, cssClass]" @onChange="onChange">
<div class="form-row c-form__row" :class="[{ first: first }, cssClass]" @on-change="onChange">
<label class="c-form-row__label" :title="row.description" :for="`form-${row.key}`">
{{ row.name }}
</label>
@@ -51,6 +51,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
formControl: this.openmct.forms.getFormControl(this.row.control),
@@ -101,7 +102,7 @@ export default {
this.valid = this.validateRow(data);
data.invalid = !this.valid;
this.$emit('onChange', data);
this.$emit('on-change', data);
},
validateRow(data) {
let valid = true;

View File

@@ -88,6 +88,7 @@ export default {
}
}
},
emits: ['on-change'],
data() {
return {
hideOptions: true,
@@ -138,7 +139,7 @@ export default {
value: newValue
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
},
hideOptions(newValue) {

View File

@@ -22,7 +22,7 @@
<template>
<div class="c-form-control--clock-display-format-fields">
<SelectField v-for="item in items" :key="item.key" :model="item" @onChange="onChange" />
<SelectField v-for="item in items" :key="item.key" :model="item" @on-change="onChange" />
</div>
</template>
@@ -39,6 +39,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
items: []
@@ -55,7 +56,7 @@ export default {
},
methods: {
onChange(data) {
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -28,7 +28,7 @@
:first="index < 1"
:value="JSON.stringify(model.value[index])"
:item="item"
@onChange="onChange"
@on-change="onChange"
/>
</span>
</template>
@@ -46,12 +46,13 @@ export default {
required: true
}
},
emits: ['on-change'],
mounted() {
this.model.items.forEach((item, index) => (item.key = `${this.model.key}.${index}`));
},
methods: {
onChange(data) {
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -22,7 +22,7 @@
<template>
<div :class="compositeCssClass">
<FormRow :css-class="item.cssClass" :first="first" :row="row" @onChange="onChange" />
<FormRow :css-class="item.cssClass" :first="first" :row="row" @on-change="onChange" />
<span class="composite-control-label">
{{ item.name }}
</span>
@@ -50,6 +50,7 @@ export default {
}
}
},
emits: ['on-change'],
computed: {
compositeCssClass() {
return `l-composite-control l-${this.item.control}`;
@@ -63,7 +64,7 @@ export default {
},
methods: {
onChange(data) {
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -85,6 +85,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
format: DATE_FORMAT,
@@ -139,7 +140,7 @@ export default {
value: new Date(timestamp).toISOString()
};
this.$emit('onChange', data);
this.$emit('on-change', data);
},
resetValues() {
this.setDatetime();

View File

@@ -52,6 +52,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
fileInfo: undefined
@@ -101,7 +102,7 @@ export default {
model: self.model,
value: fileInfo
};
self.$emit('onChange', data);
self.$emit('on-change', data);
};
fileReader.onerror = function (error) {
@@ -123,7 +124,7 @@ export default {
value: fileInfo
};
this.$emit('onChange', data);
this.$emit('on-change', data);
},
selectFile() {
this.$refs.fileInput.click();
@@ -135,7 +136,7 @@ export default {
model: this.model,
value: undefined
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -42,6 +42,7 @@ export default {
required: true
}
},
emits: ['on-change'],
methods: {
handleItemSelection(item) {
const data = {
@@ -49,7 +50,7 @@ export default {
value: item.objectPath
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -46,6 +46,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
field: this.model.value
@@ -61,7 +62,7 @@ export default {
value: this.field
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -44,6 +44,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
selected: this.model.value
@@ -56,7 +57,7 @@ export default {
value: this.selected
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -45,6 +45,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
field: this.model.value
@@ -60,7 +61,7 @@ export default {
value: this.field
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -45,6 +45,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
field: this.model.value
@@ -60,7 +61,7 @@ export default {
value: this.field
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -1,4 +1,5 @@
export default {
emits: ['on-change'],
data() {
return {
isChecked: false
@@ -13,7 +14,7 @@ export default {
value: this.isChecked
};
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
import Vue from 'vue';
import { nextTick } from 'vue';
import { createMouseEvent, createOpenMct, resetApplicationState } from '../../utils/testing';
import Menu from './menu';
@@ -186,7 +186,7 @@ describe('The Menu API', () => {
superMenuItem.dispatchEvent(mouseOverEvent);
const itemDescription = document.querySelector('.l-item-description__description');
Vue.nextTick(() => {
nextTick(() => {
expect(menuElement).not.toBeNull();
expect(itemDescription.innerText).toEqual(actionsArray[0].description);

View File

@@ -23,7 +23,7 @@ import EventEmitter from 'EventEmitter';
import mount from 'utils/mount';
import { h } from 'vue';
import MenuComponent from './components/Menu.vue';
import MenuComponent from './components/MenuComponent.vue';
import SuperMenuComponent from './components/SuperMenu.vue';
export const MENU_PLACEMENT = {
@@ -71,11 +71,6 @@ class Menu extends EventEmitter {
},
provide: {
options: this.options
},
// TODO: Remove this exception upon full migration to Vue 3
// https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#render-function-argument
compatConfig: {
RENDER_FUNCTION: false
}
});
@@ -98,11 +93,6 @@ class Menu extends EventEmitter {
},
provide: {
options: this.options
},
// TODO: Remove this exception upon full migration to Vue 3
// https://v3-migration.vuejs.org/breaking-changes/render-function-api.html#render-function-argument
compatConfig: {
RENDER_FUNCTION: false
}
});

View File

@@ -221,7 +221,7 @@ export default class ObjectAPI {
const provider = this.getProvider(identifier);
if (!provider) {
throw new Error(`No Provider Matched for keyString "${this.makeKeyString(identifier)}}"`);
throw new Error(`No Provider Matched for keyString "${this.makeKeyString(identifier)}"`);
}
if (!provider.get) {

View File

@@ -57,6 +57,7 @@
<script>
export default {
inject: ['dismiss', 'element', 'buttons', 'dismissable'],
emits: ['destroy'],
data: function () {
return {
focusIndex: -1

View File

@@ -181,6 +181,10 @@ export default class TelemetryCollection extends EventEmitter {
this.unsubscribe();
}
if (this.options.paging) {
return;
}
this.unsubscribe = this.openmct.telemetry.subscribe(
this.domainObject,
(datum) => this._processNewTelemetry(datum),
@@ -188,6 +192,10 @@ export default class TelemetryCollection extends EventEmitter {
);
}
getLastTelemetryDatum() {
return this.boundedTelemetry[this.boundedTelemetry.length - 1];
}
/**
* Filter any new telemetry (add/page, historical, subscription) based on
* time bounds and dupes
@@ -218,7 +226,9 @@ export default class TelemetryCollection extends EventEmitter {
if (
!afterEndOfBounds &&
(!beforeStartOfBounds || (this.isStrategyLatest && this.openmct.telemetry.greedyLAD()))
(!beforeStartOfBounds ||
(beforeStartOfBounds && this.options.paging) ||
(this.isStrategyLatest && this.openmct.telemetry.greedyLAD()))
) {
let isDuplicate = false;
let startIndex = this._sortedIndex(datum);
@@ -314,6 +324,10 @@ export default class TelemetryCollection extends EventEmitter {
return;
}
if (this.options.paging) {
return;
}
let startChanged = this.lastBounds.start !== bounds.start;
let endChanged = this.lastBounds.end !== bounds.end;

View File

@@ -79,6 +79,7 @@ export default {
required: true
}
},
emits: ['row-context-click'],
data() {
return {
datum: undefined,
@@ -232,7 +233,7 @@ export default {
this.timestampKey = timeSystem.key;
},
updateViewContext() {
this.$emit('rowContextClick', {
this.$emit('row-context-click', {
viewHistoricalData: true,
viewDatumAction: true,
getDatum: () => {

View File

@@ -41,7 +41,7 @@
:has-units="hasUnits"
:is-stale="staleObjects.includes(ladRow.key)"
:configuration="configuration"
@rowContextClick="updateViewContext"
@row-context-click="updateViewContext"
/>
</tbody>
</table>
@@ -49,9 +49,9 @@
</template>
<script>
import Vue, { toRaw } from 'vue';
import { nextTick, toRaw } from 'vue';
import StalenessUtils from '@/utils/staleness';
import stalenessMixin from '@/ui/mixins/staleness-mixin';
import LadRow from './LadRow.vue';
@@ -59,6 +59,7 @@ export default {
components: {
LadRow
},
mixins: [stalenessMixin],
inject: ['openmct', 'currentView', 'ladTableConfiguration'],
props: {
domainObject: {
@@ -74,7 +75,6 @@ export default {
return {
items: [],
viewContext: {},
staleObjects: [],
configuration: this.ladTableConfiguration.getConfiguration()
};
},
@@ -96,11 +96,7 @@ export default {
return !this.configuration?.hiddenColumns?.type;
},
staleClass() {
if (this.staleObjects.length !== 0) {
return 'is-stale';
}
return '';
return this.isStale ? 'is-stale' : '';
},
applyLayoutClass() {
if (this.configuration.isFixedLayout) {
@@ -133,12 +129,16 @@ export default {
this.composition.on('remove', this.removeItem);
this.composition.on('reorder', this.reorder);
this.composition.load();
this.stalenessSubscription = {};
await Vue.nextTick();
await nextTick();
this.viewActionsCollection = this.openmct.actions.getActionsCollection(
this.objectPath,
this.currentView
);
this.setupClockChangedEvent((domainObject) => {
this.triggerUnsubscribeFromStaleness(domainObject);
this.subscribeToStaleness(domainObject);
});
this.initializeViewActions();
},
unmounted() {
@@ -147,11 +147,6 @@ export default {
this.composition.off('add', this.addItem);
this.composition.off('remove', this.removeItem);
this.composition.off('reorder', this.reorder);
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
stalenessSubscription.unsubscribe();
stalenessSubscription.stalenessUtils.destroy();
});
},
methods: {
addItem(domainObject) {
@@ -160,35 +155,16 @@ export default {
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.items.push(item);
this.stalenessSubscription[item.key] = {};
this.stalenessSubscription[item.key].stalenessUtils = new StalenessUtils(
this.openmct,
domainObject
);
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
if (stalenessResponse !== undefined) {
this.handleStaleness(item.key, stalenessResponse);
}
});
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
domainObject,
(stalenessResponse) => {
this.handleStaleness(item.key, stalenessResponse);
}
);
this.stalenessSubscription[item.key].unsubscribe = stalenessSubscription;
this.subscribeToStaleness(domainObject);
},
removeItem(identifier) {
const SKIP_CHECK = true;
const keystring = this.openmct.objects.makeKeyString(identifier);
const index = this.items.findIndex((item) => keystring === item.key);
const index = this.items.findIndex((item) => keystring === item.key);
this.items.splice(index, 1);
this.stalenessSubscription[keystring].unsubscribe();
this.handleStaleness(keystring, { isStale: false }, SKIP_CHECK);
const domainObject = this.openmct.objects.get(keystring);
this.triggerUnsubscribeFromStaleness(domainObject);
},
reorder(reorderPlan) {
const oldItems = this.items.slice();
@@ -204,23 +180,6 @@ export default {
handleConfigurationChange(configuration) {
this.configuration = configuration;
},
handleStaleness(id, stalenessResponse, skipCheck = false) {
if (
skipCheck ||
this.stalenessSubscription[id].stalenessUtils.shouldUpdateStaleness(stalenessResponse)
) {
const index = this.staleObjects.indexOf(id);
if (stalenessResponse.isStale) {
if (index === -1) {
this.staleObjects.push(id);
}
} else {
if (index !== -1) {
this.staleObjects.splice(index, 1);
}
}
}
},
updateViewContext(rowContext) {
this.viewContext.row = rowContext;
},

View File

@@ -45,9 +45,9 @@
:domain-object="ladRow.domainObject"
:path-to-table="ladTable.objectPath"
:has-units="hasUnits"
:is-stale="staleObjects.includes(combineKeys(ladTable.key, ladRow.key))"
:is-stale="staleObjects.includes(ladRow.key)"
:configuration="configuration"
@rowContextClick="updateViewContext"
@row-context-click="updateViewContext"
/>
</template>
</tbody>
@@ -56,7 +56,9 @@
</template>
<script>
import StalenessUtils from '@/utils/staleness';
import { toRaw } from 'vue';
import stalenessMixin from '@/ui/mixins/staleness-mixin';
import LadRow from './LadRow.vue';
@@ -64,6 +66,7 @@ export default {
components: {
LadRow
},
mixins: [stalenessMixin],
inject: ['openmct', 'objectPath', 'currentView', 'ladTableConfiguration'],
props: {
domainObject: {
@@ -76,8 +79,8 @@ export default {
ladTableObjects: [],
ladTelemetryObjects: {},
viewContext: {},
staleObjects: [],
configuration: this.ladTableConfiguration.getConfiguration()
configuration: this.ladTableConfiguration.getConfiguration(),
subscribedObjects: {}
};
},
computed: {
@@ -108,11 +111,7 @@ export default {
return !this.configuration?.hiddenColumns?.type;
},
staleClass() {
if (this.staleObjects.length !== 0) {
return 'is-stale';
}
return '';
return this.isStale ? 'is-stale' : '';
}
},
created() {
@@ -125,8 +124,10 @@ export default {
this.composition.on('remove', this.removeLadTable);
this.composition.on('reorder', this.reorderLadTables);
this.composition.load();
this.stalenessSubscription = {};
this.setupClockChangedEvent((domainObject) => {
this.triggerUnsubscribeFromStaleness(domainObject);
this.subscribeToStaleness(domainObject);
});
},
unmounted() {
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
@@ -137,11 +138,6 @@ export default {
c.composition.off('add', c.addCallback);
c.composition.off('remove', c.removeCallback);
});
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
stalenessSubscription.unsubscribe();
stalenessSubscription.stalenessUtils.destroy();
});
},
methods: {
addLadTable(domainObject) {
@@ -176,9 +172,18 @@ export default {
);
let ladTable = this.ladTableObjects[index];
this.ladTelemetryObjects[ladTable.key].forEach((telemetryObject) => {
let combinedKey = this.combineKeys(ladTable.key, telemetryObject.key);
this.unwatchStaleness(combinedKey);
ladTable?.domainObject?.composition.forEach((telemetryObject) => {
const telemetryKey = this.openmct.objects.makeKeyString(telemetryObject);
if (!this.subscribedObjects?.[telemetryKey]) {
return;
}
let subscribedObject = toRaw(this.subscribedObjects[telemetryKey]);
if (subscribedObject?.count > 1) {
subscribedObject.count -= 1;
} else if (subscribedObject?.count === 1) {
this.triggerUnsubscribeFromStaleness(subscribedObject.domainObject);
delete this.subscribedObjects[telemetryKey];
}
});
delete this.ladTelemetryObjects[ladTable.key];
@@ -187,11 +192,7 @@ export default {
reorderLadTables(reorderPlan) {
let oldComposition = this.ladTableObjects.slice();
reorderPlan.forEach((reorderEvent) => {
this.$set(
this.ladTableObjects,
reorderEvent.newIndex,
oldComposition[reorderEvent.oldIndex]
);
this.ladTableObjects[reorderEvent.newIndex] = oldComposition[reorderEvent.oldIndex];
});
},
addTelemetryObject(ladTable) {
@@ -199,77 +200,35 @@ export default {
let telemetryObject = {};
telemetryObject.key = this.openmct.objects.makeKeyString(domainObject.identifier);
telemetryObject.domainObject = domainObject;
const combinedKey = this.combineKeys(ladTable.key, telemetryObject.key);
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
telemetryObjects.push(telemetryObject);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
this.stalenessSubscription[combinedKey] = {};
this.stalenessSubscription[combinedKey].stalenessUtils = new StalenessUtils(
this.openmct,
domainObject
);
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
if (stalenessResponse !== undefined) {
this.handleStaleness(combinedKey, stalenessResponse);
}
});
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
domainObject,
(stalenessResponse) => {
this.handleStaleness(combinedKey, stalenessResponse);
}
);
this.stalenessSubscription[combinedKey].unsubscribe = stalenessSubscription;
if (!this.subscribedObjects[telemetryObject?.key]) {
this.subscribeToStaleness(domainObject);
this.subscribedObjects[telemetryObject?.key] = { count: 1, domainObject };
} else if (this.subscribedObjects?.[telemetryObject?.key]?.count) {
this.subscribedObjects[telemetryObject?.key].count += 1;
}
};
},
removeTelemetryObject(ladTable) {
return (identifier) => {
const keystring = this.openmct.objects.makeKeyString(identifier);
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
const combinedKey = this.combineKeys(ladTable.key, keystring);
let index = telemetryObjects.findIndex(
(telemetryObject) => keystring === telemetryObject.key
);
this.unwatchStaleness(combinedKey);
telemetryObjects.splice(index, 1);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
};
},
unwatchStaleness(combinedKey) {
const SKIP_CHECK = true;
this.stalenessSubscription[combinedKey].unsubscribe();
this.stalenessSubscription[combinedKey].stalenessUtils.destroy();
this.handleStaleness(combinedKey, { isStale: false }, SKIP_CHECK);
delete this.stalenessSubscription[combinedKey];
},
handleConfigurationChange(configuration) {
this.configuration = configuration;
},
handleStaleness(combinedKey, stalenessResponse, skipCheck = false) {
if (
skipCheck ||
this.stalenessSubscription[combinedKey].stalenessUtils.shouldUpdateStaleness(
stalenessResponse
)
) {
const index = this.staleObjects.indexOf(combinedKey);
const foundStaleObject = index > -1;
if (stalenessResponse.isStale && !foundStaleObject) {
this.staleObjects.push(combinedKey);
} else if (!stalenessResponse.isStale && foundStaleObject) {
this.staleObjects.splice(index, 1);
}
}
},
updateViewContext(rowContext) {
this.viewContext.row = rowContext;
},

View File

@@ -27,7 +27,7 @@ import {
resetApplicationState,
spyOnBuiltins
} from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import LadPlugin from './plugin.js';
@@ -233,7 +233,7 @@ describe('The LAD Table', () => {
anotherTelemetryObjectPromise,
aggregateTelemetryObjectResolve
]);
await Vue.nextTick();
await nextTick();
});
it('should show one row per object in the composition', () => {
@@ -244,7 +244,7 @@ describe('The LAD Table', () => {
it('should show the most recent datum from the telemetry producing object', async () => {
const latestDatum = getLatestTelemetry(mockTelemetry, { timeFormat });
const expectedDate = utcTimeFormat(latestDatum[timeFormat]);
await Vue.nextTick();
await nextTick();
const latestDate = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
expect(latestDate).toBe(expectedDate);
const dataType = parent
@@ -254,7 +254,7 @@ describe('The LAD Table', () => {
});
it('should show aggregate telemetry type with blank data', async () => {
await Vue.nextTick();
await nextTick();
const latestData = parent
.querySelectorAll(TABLE_BODY_ROWS)[1]
.querySelectorAll('td')[2].innerText;
@@ -282,7 +282,7 @@ describe('The LAD Table', () => {
const mostRecentTelemetry = getLatestTelemetry(mockTelemetry, { timeFormat });
const rangeValue = mostRecentTelemetry[range];
const domainValue = utcTimeFormat(mostRecentTelemetry[domain]);
await Vue.nextTick();
await nextTick();
const actualDomainValue = parent.querySelector(TABLE_BODY_FIRST_ROW_SECOND_DATA).innerText;
const actualRangeValue = parent.querySelector(TABLE_BODY_FIRST_ROW_THIRD_DATA).innerText;
expect(actualRangeValue).toBe(rangeValue);
@@ -424,7 +424,7 @@ describe('The LAD Table Set', () => {
ladTableSetView = ladTableSetViewProvider.view(mockObj.ladTableSet, [mockObj.ladTableSet]);
ladTableSetView.show(child);
return Vue.nextTick();
return nextTick();
});
it('should show one row per lad table object in the composition', () => {

View File

@@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
import { createOpenMct, resetApplicationState, spyOnBuiltins } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import AutoflowTabularConstants from './AutoflowTabularConstants';
import AutoflowTabularPlugin from './AutoflowTabularPlugin';
@@ -175,7 +175,7 @@ xdescribe('AutoflowTabularPlugin', () => {
view = provider.view(testObject, [testObject]);
view.show(testContainer);
return Vue.nextTick();
return nextTick();
});
afterEach(() => {

View File

@@ -67,6 +67,7 @@ export default {
}
}
},
emits: ['subscribe', 'unsubscribe'],
data() {
return {
isZoomed: false,

View File

@@ -6,7 +6,7 @@ import BarGraphOptions from './BarGraphOptions.vue';
export default function BarGraphInspectorViewProvider(openmct) {
return {
key: BAR_GRAPH_INSPECTOR_KEY,
name: 'Bar Graph Configuration',
name: 'Config',
canView: function (selection) {
if (selection.length === 0 || selection[0].length === 0) {
return false;

View File

@@ -43,7 +43,7 @@
edit-title="Manually set the color for this bar graph series."
view-title="The color for this bar graph series."
short-label="Color"
@colorSet="setColor"
@color-set="setColor"
/>
</li>
</ul>

View File

@@ -23,9 +23,9 @@
// import BarGraph from './BarGraphPlot.vue';
import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import { BAR_GRAPH_KEY, BAR_GRAPH_VIEW } from './BarGraphConstants';
import { BAR_GRAPH_INSPECTOR_KEY, BAR_GRAPH_KEY, BAR_GRAPH_VIEW } from './BarGraphConstants';
import BarGraphPlugin from './plugin';
describe('the plugin', function () {
@@ -153,7 +153,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick();
await nextTick();
});
it('provides a bar graph view', () => {
@@ -254,7 +254,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick();
await nextTick();
});
it('Renders spectral plots', async () => {
@@ -305,8 +305,8 @@ describe('the plugin', function () {
barGraphView.show(child, true);
mockComposition.emit('add', dotFullTelemetryObject);
await Vue.nextTick();
await Vue.nextTick();
await nextTick();
await nextTick();
const plotElement = element.querySelector('.cartesianlayer .scatterlayer .trace .lines');
expect(plotElement).not.toBeNull();
@@ -578,12 +578,10 @@ describe('the plugin', function () {
child.append(viewContainer);
const applicableViews = openmct.inspectorViews.get(selection);
plotInspectorView = applicableViews.filter(
(view) => view.name === 'Bar Graph Configuration'
)[0];
plotInspectorView = applicableViews.filter((view) => view.key === BAR_GRAPH_INSPECTOR_KEY)[0];
plotInspectorView.show(viewContainer);
await Vue.nextTick();
await nextTick();
optionsElement = element.querySelector('.c-bar-graph-options');
});

View File

@@ -84,6 +84,7 @@ export default {
required: true
}
},
emits: ['on-change'],
data() {
return {
rangeMax: this.model.value.rangeMax,
@@ -119,7 +120,7 @@ export default {
this.model.validate(data);
}
this.$emit('onChange', data);
this.$emit('on-change', data);
}
}
};

View File

@@ -71,6 +71,7 @@ export default {
}
}
},
emits: ['subscribe', 'unsubscribe'],
data() {
return {
isZoomed: false,

View File

@@ -59,7 +59,7 @@
edit-title="Manually set the line and marker color for this plot."
view-title="The line and marker color for this plot."
short-label="Color"
@colorSet="setColor"
@color-set="setColor"
/>
</ul>
</div>

View File

@@ -118,7 +118,7 @@ export default function () {
onChange
};
},
template: `<scatter-plot-form :model="model" @onChange="onChange"></scatter-plot-form>`
template: `<scatter-plot-form :model="model" @on-change="onChange"></scatter-plot-form>`
},
{
app: openmct.app,

View File

@@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import ScatterPlotPlugin from './plugin';
import { SCATTER_PLOT_KEY, SCATTER_PLOT_VIEW } from './scatterPlotConstants';
@@ -178,7 +178,7 @@ describe('the plugin', function () {
spyOn(openmct.composition, 'get').and.returnValue(mockComposition);
await Vue.nextTick();
await nextTick();
});
it('provides a scatter plot view', () => {
@@ -406,7 +406,7 @@ describe('the plugin', function () {
plotInspectorView = applicableViews[0];
plotInspectorView.show(viewContainer);
await Vue.nextTick();
await nextTick();
optionsElement = element.querySelector('.c-scatter-plot-options');
});

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import { createMouseEvent, createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import ClearDataPlugin from './plugin.js';
@@ -213,7 +213,7 @@ describe('The Clear Data Plugin:', () => {
});
it('renders its major elements', async () => {
await Vue.nextTick();
await nextTick();
const indicatorClass = appHolder.querySelector('.c-indicator');
const iconClass = appHolder.querySelector('.icon-clear-data');
const indicatorLabel = appHolder.querySelector('.c-indicator__label');

View File

@@ -22,7 +22,7 @@
import mount from 'utils/mount';
import Clock from './components/Clock.vue';
import Clock from './components/ClockComponent.vue';
export default function ClockViewProvider(openmct) {
return {

View File

@@ -22,7 +22,7 @@
import EventEmitter from 'EventEmitter';
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import clockPlugin from './plugin';
@@ -106,7 +106,7 @@ describe('Clock plugin:', () => {
clockView = clockViewProvider.view(mutableClockObject);
clockView.show(child);
await Vue.nextTick();
await nextTick();
await new Promise((resolve) => requestAnimationFrame(resolve));
});
@@ -232,7 +232,7 @@ describe('Clock plugin:', () => {
it('contains text', async () => {
await setupClock(true);
await Vue.nextTick();
await nextTick();
await new Promise((resolve) => requestAnimationFrame(resolve));
clockIndicator = openmct.indicators.indicatorObjects.find(

View File

@@ -97,8 +97,10 @@ describe('The condition', function () {
mockTimeSystems = {
key: 'utc'
};
openmct.time = jasmine.createSpyObj('time', ['getAllTimeSystems']);
openmct.time = jasmine.createSpyObj('time', ['getAllTimeSystems', 'on', 'off']);
openmct.time.getAllTimeSystems.and.returnValue([mockTimeSystems]);
openmct.time.on.and.returnValue(() => {});
openmct.time.off.and.returnValue(() => {});
testConditionDefinition = {
id: '123-456',

View File

@@ -66,12 +66,12 @@
:is-editing="isEditing"
:move-index="moveIndex"
:is-dragging="isDragging"
@updateCondition="updateCondition"
@removeCondition="removeCondition"
@cloneCondition="cloneCondition"
@setMoveIndex="setMoveIndex"
@dragComplete="dragComplete"
@dropCondition="dropCondition"
@update-condition="updateCondition"
@remove-condition="removeCondition"
@clone-condition="cloneCondition"
@set-move-index="setMoveIndex"
@drag-complete="dragComplete"
@drop-condition="dropCondition"
/>
</div>
</div>
@@ -79,15 +79,16 @@
</template>
<script>
import StalenessUtils from '@/utils/staleness';
import stalenessMixin from '@/ui/mixins/staleness-mixin';
import ConditionManager from '../ConditionManager';
import Condition from './Condition.vue';
import Condition from './ConditionItem.vue';
export default {
components: {
Condition
},
mixins: [stalenessMixin],
inject: ['openmct', 'domainObject'],
props: {
isEditing: Boolean,
@@ -102,6 +103,12 @@ export default {
}
}
},
emits: [
'condition-set-result-updated',
'no-telemetry-objects',
'telemetry-updated',
'telemetry-staleness'
],
data() {
return {
expanded: true,
@@ -135,13 +142,6 @@ export default {
if (this.stopObservingForChanges) {
this.stopObservingForChanges();
}
if (this.stalenessSubscription) {
Object.values(this.stalenessSubscription).forEach((stalenessSubscription) => {
stalenessSubscription.unsubscribe();
stalenessSubscription.stalenessUtils.destroy();
});
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
@@ -153,16 +153,29 @@ export default {
this.conditionManager = new ConditionManager(this.domainObject, this.openmct);
this.conditionManager.on('conditionSetResultUpdated', this.handleConditionSetResultUpdated);
this.conditionManager.on('noTelemetryObjects', this.emitNoTelemetryObjectEvent);
this.stalenessSubscription = {};
this.setupClockChangedEvent((domainObject) => {
this.triggerUnsubscribeFromStaleness(domainObject, () => {
this.emitStaleness({
keyString: domainObject.identifier,
stalenessResponse: { isStale: false }
});
});
this.subscribeToStaleness(domainObject, (stalenessResponse) => {
this.emitStaleness({
keyString: domainObject.identifier,
stalenessResponse: stalenessResponse
});
});
});
},
methods: {
handleConditionSetResultUpdated(data) {
this.currentConditionId = data.conditionId;
this.$emit('conditionSetResultUpdated', data);
this.$emit('condition-set-result-updated', data);
},
emitNoTelemetryObjectEvent(data) {
this.currentConditionId = '';
this.$emit('noTelemetryObjects');
this.$emit('no-telemetry-objects');
},
observeForChanges() {
this.stopObservingForChanges = this.openmct.objects.observe(
@@ -219,30 +232,14 @@ export default {
const keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
this.telemetryObjs.push(domainObject);
this.$emit('telemetryUpdated', this.telemetryObjs);
this.$emit('telemetry-updated', this.telemetryObjs);
if (!this.stalenessSubscription[keyString]) {
this.stalenessSubscription[keyString] = {};
}
this.stalenessSubscription[keyString].stalenessUtils = new StalenessUtils(
this.openmct,
domainObject
);
this.openmct.telemetry.isStale(domainObject).then((stalenessResponse) => {
if (stalenessResponse !== undefined) {
this.handleStaleness(keyString, stalenessResponse);
}
this.subscribeToStaleness(domainObject, (stalenessResponse) => {
this.emitStaleness({
keyString,
stalenessResponse: stalenessResponse
});
});
const stalenessSubscription = this.openmct.telemetry.subscribeToStaleness(
domainObject,
(stalenessResponse) => {
this.handleStaleness(keyString, stalenessResponse);
}
);
this.stalenessSubscription[keyString].unsubscribe = stalenessSubscription;
},
removeTelemetryObject(identifier) {
const keyString = this.openmct.objects.makeKeyString(identifier);
@@ -252,34 +249,20 @@ export default {
return objId === keyString;
});
const domainObject = this.telemetryObjs[index];
this.triggerUnsubscribeFromStaleness(domainObject, () => {
this.emitStaleness({
keyString,
stalenessResponse: { isStale: false }
});
});
if (index > -1) {
this.telemetryObjs.splice(index, 1);
}
if (this.stalenessSubscription[keyString]) {
this.stalenessSubscription[keyString].unsubscribe();
this.stalenessSubscription[keyString].stalenessUtils.destroy();
this.emitStaleness({
keyString,
isStale: false
});
delete this.stalenessSubscription[keyString];
}
},
handleStaleness(keyString, stalenessResponse) {
if (
this.stalenessSubscription[keyString].stalenessUtils.shouldUpdateStaleness(
stalenessResponse
)
) {
this.emitStaleness({
keyString,
isStale: stalenessResponse.isStale
});
}
},
emitStaleness(stalenessObject) {
this.$emit('telemetryStaleness', stalenessObject);
this.$emit('telemetry-staleness', stalenessObject);
},
addCondition() {
this.conditionManager.addCondition();

View File

@@ -189,7 +189,7 @@ import { v4 as uuid } from 'uuid';
import { TRIGGER, TRIGGER_LABEL } from '@/plugins/condition/utils/constants';
import ConditionDescription from './ConditionDescription.vue';
import Criterion from './Criterion.vue';
import Criterion from './CriterionItem.vue';
export default {
components: {
@@ -229,6 +229,14 @@ export default {
default: 0
}
},
emits: [
'set-move-index',
'drag-complete',
'drop-condition',
'remove-condition',
'clone-condition',
'update-condition'
],
data() {
return {
currentCriteria: this.currentCriteria,
@@ -313,11 +321,11 @@ export default {
event.dataTransfer.setData('dragging', event.target); // required for FF to initiate drag
event.dataTransfer.effectAllowed = 'copyMove';
event.dataTransfer.setDragImage(event.target.closest('.c-condition-h'), 0, 0);
this.$emit('setMoveIndex', this.conditionIndex);
this.$emit('set-move-index', this.conditionIndex);
},
dragEnd() {
this.dragStarted = false;
this.$emit('dragComplete');
this.$emit('drag-complete');
},
dropCondition(event, targetIndex) {
if (!this.isDragging) {
@@ -331,7 +339,7 @@ export default {
if (this.isValidTarget(targetIndex)) {
this.dragElement = undefined;
this.draggingOver = false;
this.$emit('dropCondition', targetIndex);
this.$emit('drop-condition', targetIndex);
}
},
dragEnter(event, targetIndex) {
@@ -359,10 +367,10 @@ export default {
},
destroy() {},
removeCondition() {
this.$emit('removeCondition', this.condition.id);
this.$emit('remove-condition', this.condition.id);
},
cloneCondition() {
this.$emit('cloneCondition', {
this.$emit('clone-condition', {
condition: this.condition,
index: this.conditionIndex
});
@@ -380,7 +388,7 @@ export default {
this.persist();
},
persist() {
this.$emit('updateCondition', {
this.$emit('update-condition', {
condition: this.condition
});
},

View File

@@ -39,22 +39,24 @@
:is-editing="isEditing"
:test-data="testData"
:telemetry="telemetryObjs"
@updateTestData="updateTestData"
@update-test-data="updateTestData"
/>
<ConditionCollection
class="c-cs__conditions"
:is-editing="isEditing"
:test-data="testData"
@conditionSetResultUpdated="updateCurrentOutput"
@noTelemetryObjects="updateCurrentOutput('---')"
@telemetryUpdated="updateTelemetry"
@telemetryStaleness="handleStaleness"
@condition-set-result-updated="updateCurrentOutput"
@no-telemetry-objects="updateCurrentOutput('---')"
@telemetry-updated="updateTelemetry"
@telemetry-staleness="handleStaleness"
/>
</div>
</div>
</template>
<script>
import stalenessMixin from '@/ui/mixins/staleness-mixin';
import ConditionCollection from './ConditionCollection.vue';
import TestData from './TestData.vue';
@@ -63,6 +65,7 @@ export default {
TestData,
ConditionCollection
},
mixins: [stalenessMixin],
inject: ['openmct', 'domainObject'],
props: {
isEditing: Boolean
@@ -71,15 +74,9 @@ export default {
return {
currentConditionOutput: '',
telemetryObjs: [],
testData: {},
staleObjects: []
testData: {}
};
},
computed: {
isStale() {
return this.staleObjects.length !== 0;
}
},
mounted() {
this.conditionSetIdentifier = this.openmct.objects.makeKeyString(this.domainObject.identifier);
this.testData = {
@@ -100,17 +97,8 @@ export default {
updateTestData(testData) {
this.testData = testData;
},
handleStaleness({ keyString, isStale }) {
const index = this.staleObjects.indexOf(keyString);
if (isStale) {
if (index === -1) {
this.staleObjects.push(keyString);
}
} else {
if (index !== -1) {
this.staleObjects.splice(index, 1);
}
}
handleStaleness({ keyString, stalenessResponse }) {
this.addOrRemoveStaleObject(keyString, stalenessResponse);
}
}
};

View File

@@ -136,6 +136,7 @@ export default {
required: true
}
},
emits: ['persist'],
data() {
return {
telemetryMetadataOptions: [],

View File

@@ -127,6 +127,7 @@ export default {
}
}
},
emits: ['update-test-data'],
data() {
return {
expanded: true,
@@ -225,7 +226,7 @@ export default {
this.updateTestData();
},
updateTestData() {
this.$emit('updateTestData', {
this.$emit('update-test-data', {
applied: this.isApplied,
conditionTestInputs: this.testInputs
});

View File

@@ -78,6 +78,7 @@
<!-- Save Styles -->
<toolbar-button
v-if="canSaveStyle"
ref="saveStyleButton"
class="c-style__toolbar-button--save c-local-controls--show-on-hover c-icon-button c-icon-button--major"
:options="saveOptions"
@click="saveItemStyle()"
@@ -120,6 +121,7 @@ export default {
required: true
}
},
emits: ['persist', 'save-style'],
computed: {
itemStyle() {
return getStylesWithoutNoneValue(this.styleItem.style);

View File

@@ -38,6 +38,7 @@
<div class="c-inspect-styles__content">
<div v-if="staticStyle" class="c-inspect-styles__style">
<StyleEditor
ref="styleEditor"
class="c-inspect-styles__editor"
:style-item="staticStyle"
:is-editing="allowEditing"

View File

@@ -52,6 +52,8 @@ export default class TelemetryCriterion extends EventEmitter {
this.initialize();
this.emitEvent('criterionUpdated', this);
this.openmct.time.on('clockChanged', this.subscribeToStaleness);
}
initialize() {
@@ -95,6 +97,10 @@ export default class TelemetryCriterion extends EventEmitter {
this.unsubscribeFromStaleness();
}
if (!this.telemetryObject) {
return;
}
if (!this.stalenessUtils) {
this.stalenessUtils = new StalenessUtils(this.openmct, this.telemetryObject);
}
@@ -333,6 +339,8 @@ export default class TelemetryCriterion extends EventEmitter {
delete this.ageCheck;
}
this.openmct.time.off('clockChanged', this.subscribeToStaleness);
if (this.stalenessUtils) {
this.stalenessUtils.destroy();
}

View File

@@ -88,7 +88,9 @@ describe('The telemetry criterion', function () {
'timeSystem',
'bounds',
'getAllTimeSystems',
'getContextForView'
'getContextForView',
'on',
'off'
]);
openmct.time.timeSystem.and.returnValue({ key: 'system' });
openmct.time.bounds.and.returnValue({
@@ -97,6 +99,8 @@ describe('The telemetry criterion', function () {
});
openmct.time.getAllTimeSystems.and.returnValue([{ key: 'system' }]);
openmct.time.getContextForView.and.returnValue({});
openmct.time.on.and.returnValue(() => {});
openmct.time.off.and.returnValue(() => {});
testCriterionDefinition = {
id: 'test-criterion-id',

View File

@@ -20,8 +20,9 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
import mount from 'utils/mount';
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import ConditionManager from '@/plugins/condition/ConditionManager';
@@ -142,6 +143,7 @@ describe('the plugin', function () {
let conditionWidgetItem;
let selection;
let component;
let _destroy;
let styleViewComponentObject;
const conditionSetDomainObject = {
configuration: {
@@ -238,8 +240,7 @@ describe('the plugin', function () {
];
let viewContainer = document.createElement('div');
child.append(viewContainer);
component = new Vue({
el: viewContainer,
const { vNode, destroy } = mount({
components: {
StylesView
},
@@ -248,17 +249,20 @@ describe('the plugin', function () {
selection: selection,
stylesManager
},
template: '<styles-view/>'
template: '<styles-view ref="root"/>'
});
return Vue.nextTick().then(() => {
styleViewComponentObject = component.$root.$children[0];
component = vNode.componentInstance;
_destroy = destroy;
return nextTick().then(() => {
styleViewComponentObject = component.$refs.root;
styleViewComponentObject.setEditState(true);
});
});
afterEach(() => {
component.$destroy();
_destroy();
});
it('does not include the output label when the flag is disabled', () => {
@@ -267,7 +271,7 @@ describe('the plugin', function () {
styleViewComponentObject.initializeConditionalStyles();
expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
return Vue.nextTick().then(() => {
return nextTick().then(() => {
const hasNoOutput =
styleViewComponentObject.domainObject.configuration.objectStyles.styles.every((style) => {
return style.style.output === '' || style.style.output === undefined;
@@ -286,7 +290,7 @@ describe('the plugin', function () {
styleViewComponentObject.useConditionSetOutputAsLabel = true;
styleViewComponentObject.persistLabelConfiguration();
return Vue.nextTick().then(() => {
return nextTick().then(() => {
const outputs = styleViewComponentObject.domainObject.configuration.objectStyles.styles.map(
(style) => {
return style.style.output;
@@ -306,6 +310,7 @@ describe('the plugin', function () {
let selection;
let component;
let styleViewComponentObject;
let _destroy;
const conditionSetDomainObject = {
configuration: {
conditionTestData: [
@@ -560,8 +565,7 @@ describe('the plugin', function () {
];
let viewContainer = document.createElement('div');
child.append(viewContainer);
component = new Vue({
el: viewContainer,
const { vNode, destroy } = mount({
components: {
StylesView
},
@@ -570,15 +574,22 @@ describe('the plugin', function () {
selection: selection,
stylesManager
},
template: '<styles-view/>'
template: '<styles-view ref="root"/>'
});
return Vue.nextTick().then(() => {
styleViewComponentObject = component.$root.$children[0];
component = vNode.componentInstance;
_destroy = destroy;
return nextTick().then(() => {
styleViewComponentObject = component.$refs.root;
styleViewComponentObject.setEditState(true);
});
});
afterEach(() => {
_destroy();
});
it('initializes the items in the view', () => {
expect(styleViewComponentObject.items.length).toBe(3);
});
@@ -597,7 +608,7 @@ describe('the plugin', function () {
expect(styleViewComponentObject.conditionalStyles.length).toBe(2);
styleViewComponentObject.updateConditionalStyle(conditionalStyle, 'border');
return Vue.nextTick().then(() => {
return nextTick().then(() => {
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
[boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => {
const itemStyles =
@@ -627,7 +638,7 @@ describe('the plugin', function () {
it('updates applicable static styles', () => {
styleViewComponentObject.updateStaticStyle(staticStyle, 'border');
return Vue.nextTick().then(() => {
return nextTick().then(() => {
expect(styleViewComponentObject.domainObject.configuration.objectStyles).toBeDefined();
[boxLayoutItem, lineLayoutItem, notCreatableObjectItem].forEach((item) => {
const itemStyle =

View File

@@ -1,5 +1,5 @@
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import ConditionWidgetPlugin from './plugin';
@@ -148,7 +148,7 @@ describe('the plugin', function () {
let view = conditionWidgetView.view(testViewObject, element);
view.show(child, true);
return Vue.nextTick();
return nextTick();
});
it('provides a view', () => {
@@ -184,7 +184,7 @@ describe('the plugin', function () {
);
conditionWidgetView.show(urlChild);
await Vue.nextTick();
await nextTick();
const domainUrl = mockConditionObject[CONDITION_WIDGET_KEY].url;
expect(urlParent.innerHTML).toContain(

View File

@@ -26,7 +26,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<div
@@ -78,6 +78,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
computed: {
style() {
if (this.itemStyle) {
@@ -127,7 +128,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -57,17 +57,17 @@
:index="index"
:multi-select="selectedLayoutItems.length > 1 || null"
:is-editing="isEditing"
@contextClick="updateViewContext"
@context-click="updateViewContext"
@move="move"
@endMove="endMove"
@endLineResize="endLineResize"
@formatChanged="updateTelemetryFormat"
@end-move="endMove"
@end-line-resize="endLineResize"
@format-changed="updateTelemetryFormat"
/>
<edit-marquee
v-if="showMarquee"
:grid-size="gridSize"
:selected-layout-items="selectedLayoutItems"
@endResize="endResize"
@end-resize="endResize"
/>
</div>
</template>

View File

@@ -58,6 +58,7 @@ export default {
validator: (arr) => arr && arr.length === 2 && arr.every((el) => typeof el === 'number')
}
},
emits: ['end-resize'],
data() {
return {
dragPosition: undefined
@@ -182,7 +183,7 @@ export default {
y: marqueeEnd.y - marqueeStart.y
};
this.$emit('endResize', scaleWidth, scaleHeight, marqueeStart, marqueeOffset);
this.$emit('end-resize', scaleWidth, scaleHeight, marqueeStart, marqueeOffset);
this.dragPosition = undefined;
this.initialPosition = undefined;
this.marqueeStartPosition = undefined;

View File

@@ -26,7 +26,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<div
@@ -78,6 +78,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
computed: {
style() {
if (this.itemStyle) {
@@ -127,7 +128,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -26,7 +26,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<div class="c-image-view" :style="style"></div>
@@ -74,6 +74,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
computed: {
style() {
let backgroundImage = 'url(' + this.item.url + ')';
@@ -130,7 +131,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -56,6 +56,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
computed: {
size() {
let { width, height } = this.item;
@@ -119,7 +120,7 @@ export default {
document.body.removeEventListener('mousemove', this.continueMove);
document.body.removeEventListener('mouseup', this.endMove);
this.continueMove(event);
this.$emit('endMove');
this.$emit('end-move');
this.dragPosition = undefined;
this.initialPosition = undefined;
this.delta = undefined;

View File

@@ -108,6 +108,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move', 'end-line-resize'],
data() {
return {
dragPosition: undefined,
@@ -318,9 +319,9 @@ export default {
document.body.removeEventListener('mouseup', this.endDrag);
let { x, y, x2, y2 } = this.dragPosition;
if (!this.dragging) {
this.$emit('endMove');
this.$emit('end-move');
} else {
this.$emit('endLineResize', this.item, {
this.$emit('end-line-resize', this.item, {
x,
y,
x2,

View File

@@ -25,7 +25,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<ObjectFrame
@@ -103,6 +103,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
data() {
return {
domainObject: undefined,
@@ -174,7 +175,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -26,7 +26,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<div
@@ -126,6 +126,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move', 'format-changed', 'context-click'],
data() {
return {
currentObjectPath: undefined,
@@ -240,6 +241,11 @@ export default {
this.status = this.openmct.status.get(this.item.identifier);
this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus);
this.setupClockChangedEvent((domainObject) => {
this.triggerUnsubscribeFromStaleness(domainObject);
this.subscribeToStaleness(domainObject);
});
},
beforeUnmount() {
this.removeStatusListener();
@@ -339,10 +345,10 @@ export default {
updateTelemetryFormat(format) {
this.customStringformatter.setFormat(format);
this.$emit('formatChanged', this.item, format);
this.$emit('format-changed', this.item, format);
},
updateViewContext() {
this.$emit('contextClick', {
this.$emit('context-click', {
viewHistoricalData: true,
formattedValueForCopy: this.formattedValueForCopy
});
@@ -395,7 +401,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -26,7 +26,7 @@
:grid-size="gridSize"
:is-editing="isEditing"
@move="move"
@endMove="endMove"
@end-move="endMove"
>
<template #content>
<div
@@ -86,6 +86,7 @@ export default {
required: true
}
},
emits: ['move', 'end-move'],
computed: {
style() {
let size;
@@ -139,7 +140,7 @@ export default {
this.$emit('move', gridDelta);
},
endMove() {
this.$emit('endMove');
this.$emit('end-move');
}
}
};

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import { createOpenMct, resetApplicationState } from 'utils/testing';
import Vue from 'vue';
import { nextTick } from 'vue';
import DisplayLayoutPlugin from './plugin';
@@ -163,7 +163,7 @@ describe('the plugin', function () {
const view = displayLayoutViewProvider.view(displayLayoutItem, displayLayoutItem);
view.show(child, false);
Vue.nextTick(done);
nextTick(done);
});
it('will sync composition and layout items', () => {

View File

@@ -29,7 +29,7 @@ export default function FaultManagementInspectorViewProvider(openmct) {
return {
openmct: openmct,
key: FAULT_MANAGEMENT_INSPECTOR,
name: 'Fault Management Configuration',
name: 'Config',
canView: (selection) => {
if (selection.length !== 1 || selection[0].length === 0) {
return false;

View File

@@ -43,7 +43,7 @@
class="c-fault-mgmt-viewButton"
title="Sort By"
:model="model"
@onChange="onChange"
@on-change="onChange"
/>
</div>
</div>
@@ -74,6 +74,7 @@ export default {
}
}
},
emits: ['sort-changed', 'select-all'],
data() {
return {
model: {}
@@ -93,10 +94,10 @@ export default {
},
methods: {
onChange(data) {
this.$emit('sortChanged', data);
this.$emit('sort-changed', data);
},
selectAll(e) {
this.$emit('selectAll', e.target.checked);
this.$emit('select-all', e.target.checked);
}
}
};

View File

@@ -90,6 +90,7 @@ export default {
}
}
},
emits: ['acknowledge-selected', 'shelve-selected', 'toggle-selected'],
computed: {
classesFromState() {
const exclusiveStates = [
@@ -169,7 +170,7 @@ export default {
name: 'Acknowledge',
description: '',
onItemClicked: (e) => {
this.$emit('acknowledgeSelected', [this.fault]);
this.$emit('acknowledge-selected', [this.fault]);
}
},
{
@@ -177,7 +178,7 @@ export default {
name: 'Shelve',
description: '',
onItemClicked: () => {
this.$emit('shelveSelected', [this.fault], { shelved: true });
this.$emit('shelve-selected', [this.fault], { shelved: true });
}
},
{
@@ -186,7 +187,7 @@ export default {
name: 'Unshelve',
description: '',
onItemClicked: () => {
this.$emit('shelveSelected', [this.fault], { shelved: false });
this.$emit('shelve-selected', [this.fault], { shelved: false });
}
}
];
@@ -199,7 +200,7 @@ export default {
selected: event.target.checked
};
this.$emit('toggleSelected', faultData);
this.$emit('toggle-selected', faultData);
}
}
};

View File

@@ -24,15 +24,15 @@
<div class="c-faults-list-view">
<FaultManagementSearch
:search-term="searchTerm"
@filterChanged="updateFilter"
@updateSearchTerm="updateSearchTerm"
@filter-changed="updateFilter"
@update-search-term="updateSearchTerm"
/>
<FaultManagementToolbar
v-if="showToolbar"
:selected-faults="selectedFaults"
@acknowledgeSelected="toggleAcknowledgeSelected"
@shelveSelected="toggleShelveSelected"
@acknowledge-selected="toggleAcknowledgeSelected"
@shelve-selected="toggleShelveSelected"
/>
<div class="c-faults-list-view-header-item-container-wrapper">
@@ -41,8 +41,8 @@
class="header"
:selected-faults="Object.values(selectedFaults)"
:total-faults-count="filteredFaultsList.length"
@selectAll="selectAll"
@sortChanged="sortChanged"
@select-all="selectAll"
@sort-changed="sortChanged"
/>
<div class="c-faults-list-view-item-body">
@@ -52,9 +52,9 @@
:key="fault.id"
:fault="fault"
:is-selected="isSelected(fault)"
@toggleSelected="toggleSelected"
@acknowledgeSelected="toggleAcknowledgeSelected"
@shelveSelected="toggleShelveSelected"
@toggle-selected="toggleSelected"
@acknowledge-selected="toggleAcknowledgeSelected"
@shelve-selected="toggleShelveSelected"
/>
</template>
</div>

View File

@@ -33,14 +33,14 @@
class="c-fault-mgmt-viewButton"
title="View Filter"
:model="model"
@onChange="onChange"
@on-change="onChange"
/>
</div>
</template>
<script>
import SelectField from '@/api/forms/components/controls/SelectField.vue';
import Search from '@/ui/components/Search.vue';
import Search from '@/ui/components/SearchComponent.vue';
import { FILTER_ITEMS } from './constants';
@@ -56,6 +56,7 @@ export default {
default: ''
}
},
emits: ['filter-changed', 'update-search-term'],
data() {
return {
items: []
@@ -79,10 +80,10 @@ export default {
},
methods: {
onChange(data) {
this.$emit('filterChanged', data);
this.$emit('filter-changed', data);
},
updateSearchTerm(searchTerm) {
this.$emit('updateSearchTerm', searchTerm);
this.$emit('update-search-term', searchTerm);
}
}
};

View File

@@ -53,6 +53,7 @@ export default {
}
}
},
emits: ['acknowledge-selected', 'shelve-selected'],
data() {
return {
disableAcknowledge: true,
@@ -82,10 +83,10 @@ export default {
},
methods: {
acknowledgeSelected() {
this.$emit('acknowledgeSelected');
this.$emit('acknowledge-selected');
},
shelveSelected() {
this.$emit('shelveSelected');
this.$emit('shelve-selected');
}
}
};

View File

@@ -22,6 +22,7 @@
import { createOpenMct, resetApplicationState } from '../../utils/testing';
import {
FAULT_MANAGEMENT_INSPECTOR,
FAULT_MANAGEMENT_NAMESPACE,
FAULT_MANAGEMENT_TYPE,
FAULT_MANAGEMENT_VIEW
@@ -86,7 +87,7 @@ describe('The Fault Management Plugin', () => {
];
const applicableInspectorViews = openmct.inspectorViews.get(faultDomainObjectSelection);
const faultManagementInspectorView = applicableInspectorViews.filter(
(view) => view.name === 'Fault Management Configuration'
(view) => view.key === FAULT_MANAGEMENT_INSPECTOR
);
expect(faultManagementInspectorView.length).toEqual(1);

View File

@@ -39,8 +39,8 @@
type="text"
:aria-label="label"
:disabled="useGlobal"
:value="persistedValue(filter)"
@change="updateFilterValueFromString($event, filter)"
:value="persistedValue(filter.comparator)"
@change="updateFilterValueFromString($event, filter.comparator)"
/>
</template>
@@ -125,6 +125,12 @@ export default {
}
}
},
emits: [
'filter-text-value-changed',
'filter-selected',
'clear-filters',
'filter-single-selected'
],
data() {
return {
isEditing: this.openmct.editor.isEditing()
@@ -151,16 +157,16 @@ export default {
return this.persistedFilters && this.persistedFilters[comparator];
},
updateFilterValueFromString(event, comparator) {
this.$emit('filterTextValueChanged', this.filterField.key, comparator, event.target.value);
this.$emit('filter-text-value-changed', this.filterField.key, comparator, event.target.value);
},
updateFilterValueFromCheckbox(event, comparator, value) {
this.$emit('filterSelected', this.filterField.key, comparator, value, event.target.checked);
this.$emit('filter-selected', this.filterField.key, comparator, value, event.target.checked);
},
updateFilterValueFromDropdown(event, comparator, value) {
if (value === 'NONE') {
this.$emit('clearFilters', this.filterField.key);
this.$emit('clear-filters', this.filterField.key);
} else {
this.$emit('filterSingleSelected', this.filterField.key, comparator, value);
this.$emit('filter-single-selected', this.filterField.key, comparator, value);
}
},
getFilterLabels(filter) {

View File

@@ -64,10 +64,10 @@
:use-global="persistedFilters.useGlobal"
:persisted-filters="updatedFilters[metadatum.key]"
label="Specific Filter"
@filterSelected="updateMultipleFiltersWithSelectedValue"
@filterTextValueChanged="updateFiltersWithTextValue"
@filterSingleSelected="updateSingleSelection"
@clearFilters="clearFilters"
@filter-selected="updateMultipleFiltersWithSelectedValue"
@filter-text-value-changed="updateFiltersWithTextValue"
@filter-single-selected="updateSingleSelection"
@clear-filters="clearFilters"
/>
</ul>
</div>
@@ -98,6 +98,7 @@ export default {
}
}
},
emits: ['update-filters'],
data() {
return {
expanded: false,
@@ -161,11 +162,11 @@ export default {
this.updatedFilters[key][comparator] = [valueName];
}
this.$emit('updateFilters', this.keyString, this.updatedFilters);
this.$emit('update-filters', this.keyString, this.updatedFilters);
},
clearFilters(key) {
this.updatedFilters[key] = {};
this.$emit('updateFilters', this.keyString, this.updatedFilters);
this.$emit('update-filters', this.keyString, this.updatedFilters);
},
updateFiltersWithTextValue(key, comparator, value) {
if (value.trim() === '') {
@@ -174,15 +175,15 @@ export default {
this.updatedFilters[key][comparator] = value;
}
this.$emit('updateFilters', this.keyString, this.updatedFilters);
this.$emit('update-filters', this.keyString, this.updatedFilters);
},
updateSingleSelection(key, comparator, value) {
this.updatedFilters[key][comparator] = [value];
this.$emit('updateFilters', this.keyString, this.updatedFilters);
this.$emit('update-filters', this.keyString, this.updatedFilters);
},
useGlobalFilter(checked) {
this.updatedFilters.useGlobal = checked;
this.$emit('updateFilters', this.keyString, this.updatedFilters, checked);
this.$emit('update-filters', this.keyString, this.updatedFilters, checked);
},
toggleIsEditing(isEditing) {
this.isEditing = isEditing;

View File

@@ -28,20 +28,21 @@
<global-filters
:global-filters="globalFilters"
:global-metadata="globalMetadata"
@persistGlobalFilters="persistGlobalFilters"
@persist-global-filters="persistGlobalFilters"
/>
<filter-object
v-for="(child, key) in children"
:key="key"
:filter-object="child"
:persisted-filters="persistedFilters[key]"
@updateFilters="persistFilters"
@update-filters="persistFilters"
/>
</ul>
</template>
<script>
import _ from 'lodash';
import { toRaw } from 'vue';
import FilterObject from './FilterObject.vue';
import GlobalFilters from './GlobalFilters.vue';
@@ -155,11 +156,7 @@ export default {
mutateFilters = true;
}
this.$set(
this.persistedFilters[keyString],
metadatum.key,
this.globalFilters[metadatum.key]
);
this.persistedFilters[keyString][metadatum.key] = this.globalFilters[metadatum.key];
}
});
}
@@ -271,14 +268,14 @@ export default {
this.openmct.objects.mutate(
this.providedObject,
'configuration.filters',
this.persistedFilters
toRaw(this.persistedFilters)
);
},
mutateConfigurationGlobalFilters() {
this.openmct.objects.mutate(
this.providedObject,
'configuration.globalFilters',
this.globalFilters
toRaw(this.globalFilters)
);
}
}

View File

@@ -44,10 +44,10 @@
:filter-field="metadatum"
:persisted-filters="updatedFilters[metadatum.key]"
label="Global Filter"
@filterSelected="updateFiltersWithSelectedValue"
@filterTextValueChanged="updateFiltersWithTextValue"
@filterSingleSelected="updateSingleSelection"
@clearFilters="clearFilters"
@filter-selected="updateFiltersWithSelectedValue"
@filter-text-value-changed="updateFiltersWithTextValue"
@filter-single-selected="updateSingleSelection"
@clear-filters="clearFilters"
/>
</ul>
</li>
@@ -73,6 +73,7 @@ export default {
}
}
},
emits: ['persist-global-filters'],
data() {
return {
expanded: false,
@@ -102,7 +103,7 @@ export default {
},
clearFilters(key) {
this.updatedFilters[key] = {};
this.$emit('persistGlobalFilters', key, this.updatedFilters);
this.$emit('persist-global-filters', key, this.updatedFilters);
},
updateFiltersWithSelectedValue(key, comparator, valueName, value) {
let filterValue = this.updatedFilters[key];
@@ -121,11 +122,11 @@ export default {
this.updatedFilters[key][comparator] = [valueName];
}
this.$emit('persistGlobalFilters', key, this.updatedFilters);
this.$emit('persist-global-filters', key, this.updatedFilters);
},
updateSingleSelection(key, comparator, value) {
this.updatedFilters[key][comparator] = [value];
this.$emit('persistGlobalFilters', key, this.updatedFilters);
this.$emit('persist-global-filters', key, this.updatedFilters);
},
updateFiltersWithTextValue(key, comparator, value) {
if (value.trim() === '') {
@@ -134,7 +135,7 @@ export default {
this.updatedFilters[key][comparator] = value;
}
this.$emit('persistGlobalFilters', key, this.updatedFilters);
this.$emit('persist-global-filters', key, this.updatedFilters);
}
}
};

View File

@@ -76,7 +76,7 @@
<script>
import DropHint from './DropHint.vue';
import FrameComponent from './Frame.vue';
import FrameComponent from './FrameComponent.vue';
import ResizeHandle from './ResizeHandle.vue';
const MIN_FRAME_SIZE = 5;
@@ -111,6 +111,7 @@ export default {
required: true
}
},
emits: ['new-frame', 'move-frame', 'persist'],
computed: {
frames() {
return this.container.frames;

View File

@@ -45,6 +45,7 @@ export default {
required: true
}
},
emits: ['object-drop-to'],
data() {
return {
isMouseOver: false,

Some files were not shown because too many files have changed in this diff Show More