Compare commits

...

120 Commits

Author SHA1 Message Date
Jesse Mazzella
fdfca3ac1a Merge branch 'master' into vue3-compat-migration 2023-07-19 09:00:27 -07:00
Jesse Mazzella
62db57b758 fix: reactify yaxis config 2023-07-18 15:54:05 -07:00
Jesse Mazzella
8d2068ff3b fix: alphanumericFormat 2023-07-18 15:23:14 -07:00
Jesse Mazzella
aa8f60f672 fix: restore nextTick() 2023-07-18 15:14:11 -07:00
Jesse Mazzella
5095e87c2d chore: revert commented code in unit tests 2023-07-18 14:37:28 -07:00
Jesse Mazzella
c2749e4081 refactor: run lint:fix 2023-07-18 14:34:40 -07:00
Jesse Mazzella
67fd649416 refactor: simplify methods w/ optional chaining 2023-07-18 14:32:50 -07:00
Jesse Mazzella
c8379538b7 refactor: change variable name 2023-07-18 14:32:32 -07:00
Jesse Mazzella
826599ff57 fix: make static 2023-07-18 14:24:07 -07:00
Jesse Mazzella
75072e3c0d fix: make spellcheck static 2023-07-18 14:19:34 -07:00
Jesse Mazzella
6a1b1dbb54 fix: don't make roleChannel reactive 2023-07-18 14:14:18 -07:00
Jesse Mazzella
4fc8233c36 fix: Operator Status popup use componentInstance 2023-07-18 14:13:44 -07:00
Jesse Mazzella
fe2ae0f89f fix: respond to code review comments 2023-07-18 13:56:09 -07:00
Jesse Mazzella
8a6bbcae22 fix: modify this.selection without losing reactivity
- NOTE: There's still an issue with the tree and modifying attributes from EditProperties dialog or the BrowseBar. WRT the BrowseBar, modifying a name triggers the Location to update in the Properties Inspector Pane, which in turn triggers a `get()` and a `$refresh`, which is picked up by Proxy and changes the name back before we can save.

- The tree is sporadically picking up treeItem changes and it seems random, but could be a conflict or race condition between Mutables and Proxys of Mutables (?)
2023-07-17 15:10:24 -07:00
Jesse Mazzella
7b112365f3 Revert "fix: prevent Properties re-render from blocking object name change"
This reverts commit 8f11b0f1a2.
2023-07-17 14:55:42 -07:00
Jesse Mazzella
53fb7d7c30 fix: beforeDestroy() --> beforeUnmount() 2023-07-17 14:27:09 -07:00
John Hill
4f1a58b446 Merge branch 'master' into vue3-compat-migration 2023-07-17 14:22:05 -07:00
Jesse Mazzella
9d3709beb6 refactor: run lint:fix 2023-07-17 13:21:30 -07:00
Jesse Mazzella
0185d5fc2a fix(RestrictedNotebook): Multiple reactivity fixes
- Restore lock button reactivity

- Restore "Delete Section" reactivity without needing an observer
2023-07-17 13:21:01 -07:00
Jesse Mazzella
da63de2431 fix: observe sections so we can delete 2023-07-17 11:49:00 -07:00
Jesse Mazzella
29a492cb51 fix: ensure dependencies on computed properties remain reactive (Proxy) 2023-07-17 10:47:57 -07:00
Jesse Mazzella
637c2a5c35 refactor: use optional chaining 2023-07-17 10:47:24 -07:00
Jesse Mazzella
eca17ae3f5 fix(e2e): fix forms test selector 2023-07-17 10:20:55 -07:00
Jesse Mazzella
66738ebcde fix: viewLargeAction for Imagery 2023-07-17 10:00:56 -07:00
Jesse Mazzella
9447c609e6 fix: undo accidental find and replace 2023-07-15 19:12:33 -07:00
Jesse Mazzella
8f11b0f1a2 fix: prevent Properties re-render from blocking object name change 2023-07-15 11:27:04 -07:00
Jesse Mazzella
12085d673a Revert "fix: fixes issue causing Inspector to block object name updates"
This reverts commit 34111c98f7.
2023-07-15 09:12:22 -07:00
Jesse Mazzella
344993ae2f fix: ImageryView controls update correctly on TimeContext change
- When `timeContext` is retrieved from the Open MCT API and assigned to the data value, it becomes reactified (Proxy). Since it is wrapped in a Proxy, listeners don't trigger properly when events are emitted from the non-reactified API. Solution (for now) is to remove `this.timeContext` as a data (reactified) value, remove the `isFixed` and `canTrackDuration` computed values (which depend on changes to `this.timeContext` being detected), and manually update these when our non-reactified `timeContext` changes.
2023-07-15 08:59:41 -07:00
Jesse Mazzella
0b55361e54 style: fix tree pane width snapback issue 2023-07-15 08:03:08 -07:00
Jesse Mazzella
fae18bd1cd Merge branch 'master' into vue3-compat-migration 2023-07-15 07:45:43 -07:00
Jesse Mazzella
888c3fda6a style: fix AboutDialog 2023-07-14 17:04:35 -07:00
Jesse Mazzella
8c808d9bb8 style: fix Preview 2023-07-14 16:20:31 -07:00
Jesse Mazzella
4452b98097 style: a ton of css fixes
- Vue 3 appends itself on the given element on mount instead of replacing the mounting element, so we can get rid of a bunch of extra divs we didn't need.
- Styling fixes for ViewLarge, Preview, FormRows
- Fix sizing for Menu and SuperMenus
- Fix sizing for Forms and Locators
- Fix the Styles InspectorView horizontal pane issue
2023-07-14 16:18:20 -07:00
Jesse Mazzella
c62a314015 refactor: lint:fix 2023-07-14 14:11:41 -07:00
Jesse Mazzella
08a3cd7ade fix: Vue() --> mount() 2023-07-14 14:08:14 -07:00
Jesse Mazzella
a70859daf7 Merge branch 'master' into vue3-compat-migration 2023-07-14 14:03:47 -07:00
Jesse Mazzella
db2bdb878b fix: remove console.debug 2023-07-14 13:28:50 -07:00
Jesse Mazzella
d1f3c22d47 fix: never reactify the composition collection 2023-07-14 13:09:41 -07:00
Jesse Mazzella
315b39a5ea Revert "fix: remove private methods as they conflict with Vue3 proxy system"
This reverts commit 8cfa812241.
2023-07-14 12:59:59 -07:00
Jesse Mazzella
fc9889630b fix: toRaw before structuredClone of notebook entries 2023-07-14 12:57:25 -07:00
Jesse Mazzella
3a9cc42107 fix: update tooltips for vue 3 2023-07-14 10:13:13 -07:00
Jesse Mazzella
6c49bbaf70 fix: add observer for notebook section changes so it can detect section deletion 2023-07-14 08:14:03 -07:00
Scott Bell
9eaaa8199a can add sections 2023-07-14 16:21:50 +02:00
Andrew Henry
068ba69cde Changed 'callback' to 'onItemClicked' for popup menu items 2023-07-14 07:13:54 -07:00
Scott Bell
b2ff80f2c0 fix sections persisting on notebook load, and fixed router error 2023-07-14 15:25:41 +02:00
Jesse Mazzella
1f4408eb16 Merge branch 'master' into vue3-compat-migration 2023-07-13 21:39:32 -07:00
Jesse Mazzella
f269f33edd refactor: fix eslint warnings without losing progress 2023-07-13 15:52:45 -07:00
Jesse Mazzella
3a83f2a584 run lint:fix, adjust eslint rule for vue 3 2023-07-13 14:41:10 -07:00
Jesse Mazzella
1e19485f6d Merge branch 'master' into vue3-compat-migration 2023-07-13 13:39:42 -07:00
Jesse Mazzella
dfb4b53cd3 fix: remove debug code 2023-07-13 13:22:35 -07:00
Jesse Mazzella
a7ad89592a fix: add fallback if no child of document.body exists 2023-07-13 13:22:14 -07:00
Jesse Mazzella
a5734e80f5 fix: follow mutation events for timer configuration 2023-07-13 10:15:01 -07:00
Jesse Mazzella
6ac980c500 fix: follow mutation events for clock configuration changes 2023-07-13 10:11:54 -07:00
Jesse Mazzella
810c67a27b fix: ensure component is mounted before starting open mct 2023-07-13 10:02:04 -07:00
Jesse Mazzella
09f58ef85c fix: define _destroy 2023-07-13 09:20:46 -07:00
Jesse Mazzella
fd37d88ac4 fix: use public vue methods to get the layout ref 2023-07-13 08:35:57 -07:00
Andrew Henry
23906c7649 Remove dependency on Vue reactivity to detect changes from Toolbar API. Use mutation events instead 2023-07-12 14:51:14 -07:00
Andrew Henry
7d53ffa30f Do not make a copy of the domain object. This causes issues with Vue reactivity 2023-07-12 14:50:41 -07:00
Andrew Henry
a63c9457dd Mod the mutation API to emit event for array property when any member changes 2023-07-12 14:49:35 -07:00
Jesse Mazzella
679fe76412 fix: remove unnecessary element append 2023-07-11 21:16:51 -07:00
Jesse Mazzella
089a19c843 fix: vue warning 2023-07-11 17:11:26 -07:00
Jesse Mazzella
bb26169b88 fix: call me the memory leak destoyer 😎
- fixed some typos causing potential memory leaks
2023-07-11 14:11:09 -07:00
Jesse Mazzella
7b9958e094 fix: pass objectPath as a prop to Timer 2023-07-11 14:05:16 -07:00
Jesse Mazzella
28917443cf fix(StackedPlotItem): mounting no longer replaces the element
- viewContainer not needed
2023-07-11 13:46:58 -07:00
Jesse Mazzella
7b4e4af2bd fix: add deep: true on array watcher 2023-07-11 13:46:18 -07:00
Jesse Mazzella
34111c98f7 fix: fixes issue causing Inspector to block object name updates 2023-07-11 09:35:29 -07:00
Jesse Mazzella
d56ad6d286 fix: revert tiny-emitter changes for now 2023-07-11 09:35:09 -07:00
Scott Bell
ee454029b9 fix plan acitvity 2023-07-10 22:19:29 +02:00
Scott Bell
96af897cfd to raw the whole tagging process 2023-07-10 17:15:59 +02:00
Scott Bell
9489ee4fc4 Merge branch 'master' into vue3-compat-migration 2023-07-10 15:15:16 +02:00
Jesse Mazzella
93f3093d85 fix: mounted app no longer replaces HTMLElement 2023-07-09 16:16:14 -07:00
Jesse Mazzella
690fd4285a style: display: none no longer needed here 2023-07-09 11:05:58 -07:00
Jesse Mazzella
103ad6c995 fix: remove unused import 2023-07-09 11:05:40 -07:00
Jesse Mazzella
ffaedc97ed fix: use regular assignment instead of $set 2023-07-09 08:53:34 -07:00
Jesse Mazzella
88382797c3 fix: make notification indicator reactive again 2023-07-08 17:12:03 -07:00
Jesse Mazzella
4994433347 fix: revert emitter changes for MctPlot 2023-07-08 16:35:30 -07:00
Jesse Mazzella
c1263c3823 fix: do not convert the publicAPI to a Proxy 2023-07-08 12:04:11 -07:00
Jesse Mazzella
70b3db0f84 fix: GH code scan warnings 2023-07-08 11:42:20 -07:00
Jesse Mazzella
f20aa8c6d9 fix: typo 2023-07-08 11:39:31 -07:00
Jesse Mazzella
7db0d5191d fix: replace some $set with regular assignment 2023-07-08 10:41:14 -07:00
Jesse Mazzella
710fd2e1dc fix: use mount pattern to create Vue components 2023-07-08 10:40:14 -07:00
Jesse Mazzella
bb3a367f1d fix: expose the main Vue app on openmct 2023-07-08 10:21:28 -07:00
Jesse Mazzella
4bacbc03c1 fix: use correct distfile for webpack 2023-07-06 13:53:48 -07:00
Jesse Mazzella
fd6cb38596 fix: beforeUnmount and array handler 2023-07-06 13:53:34 -07:00
Scott Bell
41a540ab49 old object was a proxy and causing further object propagations with Object.assign 2023-07-06 16:05:48 +02:00
Jesse Mazzella
fa4bdbcdba fix: unmount AboutDialog onDestroy 2023-07-05 14:49:48 -07:00
Jesse Mazzella
fc170fd2fe fix(WIP): new Vue() -> Vue.createApp() 2023-07-05 12:08:03 -07:00
Jesse Mazzella
eefd3ac322 fix: upgrade Menu and SuperMenu to Vue 3
- fixes positioning of Menus

- ensure that Menu and SuperMenu are unmounted properly

- extract common logic for popup positioning into a mixin
2023-07-03 16:01:18 -07:00
Jesse Mazzella
3338e594f1 refactor: PopupMenu to use MenuAPI 2023-07-03 10:28:54 -07:00
Scott Bell
43f10befac fix infinite loop issue 2023-07-03 14:09:50 +02:00
Jesse Mazzella
c994d05c78 fix(TTable): horizontal header scroll, etc
- remove unnecessary `nextTick()`s

- `const` -> `let`
2023-06-30 10:40:16 -07:00
Jesse Mazzella
44cbbe9791 Revert "chore: pin versions"
This reverts commit 120e907486.
2023-06-29 15:53:45 -07:00
Jesse Mazzella
d8f0b6e3a8 Merge branch 'master' into vue3-compat-migration 2023-06-29 15:19:41 -07:00
Jesse Mazzella
45bd00bea6 chore: run lint:fix 2023-06-29 15:15:59 -07:00
Jesse Mazzella
120e907486 chore: pin versions 2023-06-29 14:26:21 -07:00
Jesse Mazzella
fd848972b4 fix: misc fixes 2023-06-29 14:08:50 -07:00
Jesse Mazzella
ac1e1ef54c fix: restore call $destroy on Objects 2023-06-29 09:50:17 -07:00
Jesse Mazzella
22796377c7 fix: use $refs and replace $on, $off, $once with tiny-emitter 2023-06-23 14:50:44 -07:00
Jesse Mazzella
55ebfcdf7c fix: use deep: true option for watched arrays 2023-06-23 14:48:48 -07:00
Jesse Mazzella
68ac6b6fc2 fix: warning for boolean coercion 2023-06-23 14:48:23 -07:00
Jesse Mazzella
59bde3151d fix: use regular js assignment isntead of $set 2023-06-23 14:46:18 -07:00
Jesse Mazzella
90459c3d41 fix: TelemetryTable migration
- Replace `.$el` with refs
- Use `toRaw()` to unwrap reactive Proxy for comparison
2023-06-21 14:51:32 -07:00
Jesse Mazzella
8cfa812241 fix: remove private methods as they conflict with Vue3 proxy system 2023-06-20 15:47:33 -07:00
Jesse Mazzella
609b3c2b1b fix: inspectorViews selected tab 2023-06-20 15:47:06 -07:00
Jesse Mazzella
12a0a6f7b2 fix: click handler for ImageryView 2023-06-20 15:46:36 -07:00
Jesse Mazzella
5438711228 chore: update array watchers 2023-06-15 16:49:48 -07:00
Jesse Mazzella
9f66843ed6 chore: do not convert conductor to proxy, ever 2023-06-15 16:47:58 -07:00
Jesse Mazzella
bc61b32930 chore: REVISIT: not sure this is the right way to do this but makes the objectView work 2023-06-15 16:47:41 -07:00
Jesse Mazzella
8fce444885 chore: destroy all $destroy()s 2023-06-15 16:47:01 -07:00
Jesse Mazzella
41d280934e chore: add div for mount 2023-06-15 16:42:35 -07:00
Jesse Mazzella
afce9344f4 chore: update webpack 2023-06-15 16:41:23 -07:00
Jesse Mazzella
432295606d chore destroyed: --> unmounted: 2023-06-15 11:01:41 -07:00
Jesse Mazzella
5bdfa04eb4 chore: destroyed() --> unmounted() 2023-06-15 10:47:02 -07:00
Jesse Mazzella
e7d9e37fc7 chore: use createApp in MCT.js 2023-06-15 10:45:47 -07:00
Jesse Mazzella
2896520d37 chore: beforeDestroy() --> beforeUnmount() 2023-06-14 11:41:52 -07:00
Jesse Mazzella
6610793a8d chore: fix warnings
- move `v-bind` to first property
- remove `.native()` method
2023-06-14 11:41:31 -07:00
Jesse Mazzella
e3dffc5c12 chore: update vue alias 2023-06-14 11:37:06 -07:00
Jesse Mazzella
e323d4f441 chore: add dependencies, modify webpack 2023-06-14 09:25:30 -07:00
Jesse Mazzella
3f7d071347 fix: more deprecated slot syntax 2023-06-13 15:40:19 -07:00
Jesse Mazzella
5169676eb0 fix: update usage of named slots 2023-06-13 15:36:29 -07:00
248 changed files with 2688 additions and 2121 deletions

View File

@@ -28,6 +28,8 @@ module.exports = {
}
},
rules: {
'vue/no-v-for-template-key': 'off',
'vue/no-v-for-template-key-on-child': 'error',
'prettier/prettier': 'error',
'you-dont-need-lodash-underscore/omit': 'off',
'you-dont-need-lodash-underscore/throttle': 'off',

View File

@@ -67,7 +67,8 @@ 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')
utils: path.join(projectRootDir, 'src/utils'),
vue: path.join(projectRootDir, 'node_modules/@vue/compat/dist/vue.esm-bundler.js'),
}
},
plugins: [
@@ -121,7 +122,15 @@ const config = {
},
{
test: /\.vue$/,
use: 'vue-loader'
loader: 'vue-loader',
options: {
compilerOptions: {
whitespace: 'preserve',
compatConfig: {
MODE: 2
}
}
}
},
{
test: /\.html$/,

View File

@@ -25,11 +25,6 @@ module.exports = merge(common, {
'**/.*' // dotfiles and dotfolders
]
},
resolve: {
alias: {
vue: path.join(projectRootDir, 'node_modules/vue/dist/vue.js')
}
},
plugins: [
new webpack.DefinePlugin({
__OPENMCT_ROOT_RELATIVE__: '"dist/"'

View File

@@ -13,11 +13,6 @@ const projectRootDir = path.resolve(__dirname, '..');
module.exports = merge(common, {
mode: 'production',
resolve: {
alias: {
vue: path.join(projectRootDir, 'node_modules/vue/dist/vue.min.js')
}
},
plugins: [
new webpack.DefinePlugin({
__OPENMCT_ROOT_RELATIVE__: '""'

View File

@@ -41,7 +41,7 @@ test.describe('Form Validation Behavior', () => {
await page.goto('./', { waitUntil: 'domcontentloaded' });
await page.click('button:has-text("Create")');
await page.click(':nth-match(:text("Folder"), 2)');
await page.getByRole('menuitem', { name: ' Folder' }).click();
// Fill in empty string into title and trigger validation with 'Tab'
await page.click('text=Properties Title Notes >> input[type="text"]');

View File

@@ -24,7 +24,7 @@ function SimpleVuePlugin() {
container.appendChild(vm.$mount().$el);
},
destroy: function (container) {
vm.$destroy();
//vm.$destroy();
}
};
}

View File

@@ -92,7 +92,9 @@
}
</style>
</head>
<body></body>
<body>
<div id="app"></div>
</body>
<script>
const THIRTY_SECONDS = 30 * 1000;
const ONE_MINUTE = THIRTY_SECONDS * 2;

View File

@@ -12,6 +12,8 @@
"@types/eventemitter3": "1.2.0",
"@types/jasmine": "4.3.4",
"@types/lodash": "4.14.192",
"@vue/compat": "^3.1.0",
"@vue/compiler-sfc": "^3.1.0",
"babel-loader": "9.1.0",
"babel-plugin-istanbul": "6.1.1",
"codecov": "3.8.3",
@@ -22,8 +24,8 @@
"d3-scale": "3.3.0",
"d3-selection": "3.0.0",
"eslint": "8.43.0",
"eslint-plugin-compat": "4.1.4",
"eslint-config-prettier": "8.8.0",
"eslint-plugin-compat": "4.1.4",
"eslint-plugin-playwright": "0.12.0",
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-vue": "9.15.0",
@@ -66,11 +68,10 @@
"style-loader": "3.3.3",
"typescript": "5.1.3",
"uuid": "9.0.0",
"vue": "2.6.14",
"vue": "^3.1.0",
"vue-eslint-parser": "9.3.1",
"vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14",
"webpack": "5.88.0",
"vue-loader": "^16.0.0",
"webpack-cli": "5.1.1",
"webpack-dev-server": "4.15.1",
"webpack-merge": "5.9.0"

View File

@@ -343,7 +343,17 @@ define([
* @param {HTMLElement} [domElement] the DOM element in which to run
* MCT; if undefined, MCT will be run in the body of the document
*/
MCT.prototype.start = function (domElement = document.body, isHeadlessMode = false) {
MCT.prototype.start = function (
domElement = document.body.firstElementChild,
isHeadlessMode = false
) {
// Create element to mount Layout if it doesn't exist
if (domElement === null) {
domElement = document.createElement('div');
document.body.appendChild(domElement);
}
domElement.id = 'openmct-app';
if (this.types.get('layout') === undefined) {
this.install(
this.plugins.DisplayLayout({
@@ -370,25 +380,30 @@ define([
*/
if (!isHeadlessMode) {
const appLayout = new Vue({
const appLayout = Vue.createApp({
components: {
Layout: Layout.default
},
provide: {
openmct: this
openmct: Vue.markRaw(this)
},
template: '<Layout ref="layout"></Layout>'
});
domElement.appendChild(appLayout.$mount().$el);
const component = appLayout.mount(domElement);
component.$nextTick(() => {
this.layout = component.$refs.layout;
this.app = appLayout;
Browse(this);
window.addEventListener('beforeunload', this.destroy);
this.router.start();
this.emit('start');
});
} else {
window.addEventListener('beforeunload', this.destroy);
this.layout = appLayout.$refs.layout;
Browse(this);
this.router.start();
this.emit('start');
}
window.addEventListener('beforeunload', this.destroy);
this.router.start();
this.emit('start');
};
MCT.prototype.startHeadless = function () {

View File

@@ -21,6 +21,7 @@
*****************************************************************************/
import objectUtils from '../objects/object-utils';
import CompositionProvider from './CompositionProvider';
import { toRaw } from 'vue';
/**
* @typedef {import('../objects/ObjectAPI').DomainObject} DomainObject
@@ -167,7 +168,7 @@ export default class DefaultCompositionProvider extends CompositionProvider {
*/
add(parent, childId) {
if (!this.includes(parent, childId)) {
const composition = structuredClone(parent.composition);
const composition = structuredClone(toRaw(parent.composition));
composition.push(childId);
this.publicAPI.objects.mutate(parent, 'composition', composition);
}

View File

@@ -10,8 +10,7 @@ import TextAreaField from './components/controls/TextAreaField.vue';
import TextField from './components/controls/TextField.vue';
import ToggleSwitchField from './components/controls/ToggleSwitchField.vue';
import Vue from 'vue';
import mount from 'utils/mount';
export const DEFAULT_CONTROLS_MAP = {
autocomplete: AutoCompleteField,
checkbox: CheckBoxField,
@@ -69,31 +68,40 @@ export default class FormControl {
*/
_getControlViewProvider(control) {
const self = this;
let rowComponent;
let _destroy = null;
return {
show(element, model, onChange) {
rowComponent = new Vue({
el: element,
components: {
FormControlComponent: DEFAULT_CONTROLS_MAP[control]
const { vNode, destroy } = mount(
{
el: element,
components: {
FormControlComponent: DEFAULT_CONTROLS_MAP[control]
},
provide: {
openmct: self.openmct
},
data() {
return {
model,
onChange
};
},
template: `<FormControlComponent :model="model" @onChange="onChange"></FormControlComponent>`
},
provide: {
openmct: self.openmct
},
data() {
return {
model,
onChange
};
},
template: `<FormControlComponent :model="model" @onChange="onChange"></FormControlComponent>`
});
{
element,
app: self.openmct.app
}
);
_destroy = destroy;
return rowComponent;
return vNode;
},
destroy() {
rowComponent.$destroy();
if (_destroy) {
_destroy();
}
}
};
}

View File

@@ -23,8 +23,8 @@
import FormController from './FormController';
import FormProperties from './components/FormProperties.vue';
import Vue from 'vue';
import _ from 'lodash';
import mount from 'utils/mount';
export default class FormsAPI {
constructor(openmct) {
@@ -156,25 +156,28 @@ export default class FormsAPI {
formCancel = onFormAction(reject);
});
const vm = new Vue({
components: { FormProperties },
provide: {
openmct: self.openmct
const { destroy } = mount(
{
components: { FormProperties },
provide: {
openmct: self.openmct
},
data() {
return {
formStructure,
onChange: onFormPropertyChange,
onCancel: formCancel,
onSave: formSave
};
},
template:
'<FormProperties :model="formStructure" @onChange="onChange" @onCancel="onCancel" @onSave="onSave"></FormProperties>'
},
data() {
return {
formStructure,
onChange: onFormPropertyChange,
onCancel: formCancel,
onSave: formSave
};
},
template:
'<FormProperties :model="formStructure" @onChange="onChange" @onCancel="onCancel" @onSave="onSave"></FormProperties>'
}).$mount();
const formElement = vm.$el;
element.append(formElement);
{
element,
app: self.openmct.app
}
);
function onFormPropertyChange(data) {
if (onChange) {
@@ -195,8 +198,7 @@ export default class FormsAPI {
function onFormAction(callback) {
return () => {
formElement.remove();
vm.$destroy();
destroy();
if (callback) {
callback(changes);

View File

@@ -141,7 +141,7 @@ export default {
},
methods: {
onChange(data) {
this.$set(this.invalidProperties, data.model.key, data.invalid);
this.invalidProperties[data.model.key] = data.invalid;
this.$emit('onChange', data);
},

View File

@@ -26,9 +26,7 @@
{{ row.name }}
</div>
<div class="c-form-row__state-indicator" :class="reqClass"></div>
<div v-if="row.control" class="c-form-row__controls">
<div ref="rowElement"></div>
</div>
<div v-if="row.control" ref="rowElement" class="c-form-row__controls"></div>
</div>
</template>
@@ -91,7 +89,7 @@ export default {
this.formControl.show(this.$refs.rowElement, this.row, this.onChange);
},
destroyed() {
unmounted() {
const destroy = this.formControl.destroy;
if (destroy) {
destroy();

View File

@@ -166,7 +166,7 @@ export default {
this.options = this.model.options;
}
},
destroyed() {
unmounted() {
document.body.removeEventListener('click', this.handleOutsideClick);
},
methods: {

View File

@@ -20,17 +20,17 @@
at runtime from the About dialog for additional information.
-->
<template>
<div class="c-menu" :class="options.menuClass">
<div class="c-menu" :class="options.menuClass" :style="styleObject">
<ul v-if="options.actions.length && options.actions[0].length" role="menu">
<template v-for="(actionGroups, index) in options.actions">
<div :key="index" role="group">
<template v-for="(actionGroups, index) in options.actions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description"
:data-testid="action.testId || false"
:data-testid="action.testId || null"
@click="action.onItemClicked"
>
{{ action.name }}
@@ -42,8 +42,8 @@
class="c-menu__section-separator"
></div>
<li v-if="actionGroups.length === 0" :key="index">No actions defined.</li>
</div></template
>
</div>
</template>
</ul>
<ul v-else role="menu">
@@ -53,7 +53,7 @@
role="menuitem"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description"
:data-testid="action.testId || false"
:data-testid="action.testId || null"
@click="action.onItemClicked"
>
{{ action.name }}
@@ -64,7 +64,9 @@
</template>
<script>
import popupMenuMixin from '../mixins/popupMenuMixin';
export default {
mixins: [popupMenuMixin],
inject: ['options']
};
</script>

View File

@@ -20,21 +20,21 @@
at runtime from the About dialog for additional information.
-->
<template>
<div class="c-menu" :class="[options.menuClass, 'c-super-menu']">
<div class="c-menu" :class="[options.menuClass, 'c-super-menu']" :style="styleObject">
<ul
v-if="options.actions.length && options.actions[0].length"
role="menu"
class="c-super-menu__menu"
>
<template v-for="(actionGroups, index) in options.actions">
<div :key="index" role="group">
<template v-for="(actionGroups, index) in options.actions" :key="index">
<div role="group">
<li
v-for="action in actionGroups"
:key="action.name"
role="menuitem"
:class="[action.cssClass, action.isDisabled ? 'disabled' : '']"
:title="action.description"
:data-testid="action.testId || false"
:data-testid="action.testId || null"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
@@ -58,7 +58,8 @@
:key="action.name"
role="menuitem"
:class="action.cssClass"
:data-testid="action.testId || false"
:title="action.description"
:data-testid="action.testId || null"
@click="action.onItemClicked"
@mouseover="toggleItemDescription(action)"
@mouseleave="toggleItemDescription()"
@@ -79,9 +80,10 @@
</div>
</div>
</template>
<script>
import popupMenuMixin from '../mixins/popupMenuMixin';
export default {
mixins: [popupMenuMixin],
inject: ['options'],
data: function () {
return {

View File

@@ -22,7 +22,8 @@
import EventEmitter from 'EventEmitter';
import MenuComponent from './components/Menu.vue';
import SuperMenuComponent from './components/SuperMenu.vue';
import Vue from 'vue';
import { h } from 'vue';
import mount from 'utils/mount';
export const MENU_PLACEMENT = {
TOP: 'top',
@@ -52,137 +53,67 @@ class Menu extends EventEmitter {
dismiss() {
this.emit('destroy');
document.body.removeChild(this.component.$el);
if (this.destroy) {
this.destroy();
this.destroy = null;
}
document.removeEventListener('click', this.dismiss);
this.component.$destroy();
}
show() {
this.component.$mount();
document.body.appendChild(this.component.$el);
let position = this._calculatePopupPosition(this.component.$el);
this.component.$el.style.left = `${position.x}px`;
this.component.$el.style.top = `${position.y}px`;
document.addEventListener('click', this.dismiss);
}
showMenu() {
this.component = new Vue({
components: {
MenuComponent
if (this.destroy) {
return;
}
const { vNode, destroy } = mount({
render() {
return h(MenuComponent);
},
provide: {
options: this.options
},
template: '<menu-component />'
// 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
}
});
this.el = vNode.el;
this.destroy = destroy;
this.show();
}
showSuperMenu() {
this.component = new Vue({
components: {
SuperMenuComponent
const { vNode, destroy } = mount({
data() {
return {
top: '0px',
left: '0px'
};
},
render() {
return h(SuperMenuComponent);
},
provide: {
options: this.options
},
template: '<super-menu-component />'
// 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
}
});
this.el = vNode.el;
this.destroy = destroy;
this.show();
}
/**
* @private
*/
_calculatePopupPosition(menuElement) {
let menuDimensions = menuElement.getBoundingClientRect();
if (!this.options.placement) {
this.options.placement = MENU_PLACEMENT.BOTTOM_RIGHT;
}
const menuPosition = this._getMenuPositionBasedOnPlacement(menuDimensions);
return this._preventMenuOverflow(menuPosition, menuDimensions);
}
/**
* @private
*/
_getMenuPositionBasedOnPlacement(menuDimensions) {
let eventPosX = this.options.x;
let eventPosY = this.options.y;
// Adjust popup menu based on placement
switch (this.options.placement) {
case MENU_PLACEMENT.TOP:
eventPosX = this.options.x - Math.floor(menuDimensions.width / 2);
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.BOTTOM:
eventPosX = this.options.x - Math.floor(menuDimensions.width / 2);
break;
case MENU_PLACEMENT.LEFT:
eventPosX = this.options.x - menuDimensions.width;
eventPosY = this.options.y - Math.floor(menuDimensions.height / 2);
break;
case MENU_PLACEMENT.RIGHT:
eventPosY = this.options.y - Math.floor(menuDimensions.height / 2);
break;
case MENU_PLACEMENT.TOP_LEFT:
eventPosX = this.options.x - menuDimensions.width;
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.TOP_RIGHT:
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.BOTTOM_LEFT:
eventPosX = this.options.x - menuDimensions.width;
break;
case MENU_PLACEMENT.BOTTOM_RIGHT:
break;
}
return {
x: eventPosX,
y: eventPosY
};
}
/**
* @private
*/
_preventMenuOverflow(menuPosition, menuDimensions) {
let { x: eventPosX, y: eventPosY } = menuPosition;
let overflowX = eventPosX + menuDimensions.width - document.body.clientWidth;
let overflowY = eventPosY + menuDimensions.height - document.body.clientHeight;
if (overflowX > 0) {
eventPosX = eventPosX - overflowX;
}
if (overflowY > 0) {
eventPosY = eventPosY - overflowY;
}
if (eventPosX < 0) {
eventPosX = 0;
}
if (eventPosY < 0) {
eventPosY = 0;
}
return {
x: eventPosX,
y: eventPosY
};
show() {
document.body.appendChild(this.el);
document.addEventListener('click', this.dismiss);
}
}

View File

@@ -0,0 +1,111 @@
import { MENU_PLACEMENT } from '../menu';
export default {
methods: {
/**
* @private
*/
_calculatePopupPosition(menuElement) {
let menuDimensions = menuElement.getBoundingClientRect();
if (!this.options.placement) {
this.options.placement = MENU_PLACEMENT.BOTTOM_RIGHT;
}
const menuPosition = this._getMenuPositionBasedOnPlacement(menuDimensions);
return this._preventMenuOverflow(menuPosition, menuDimensions);
},
/**
* @private
*/
_getMenuPositionBasedOnPlacement(menuDimensions) {
let eventPosX = this.options.x;
let eventPosY = this.options.y;
// Adjust popup menu based on placement
switch (this.options.placement) {
case MENU_PLACEMENT.TOP:
eventPosX = this.options.x - Math.floor(menuDimensions.width / 2);
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.BOTTOM:
eventPosX = this.options.x - Math.floor(menuDimensions.width / 2);
break;
case MENU_PLACEMENT.LEFT:
eventPosX = this.options.x - menuDimensions.width;
eventPosY = this.options.y - Math.floor(menuDimensions.height / 2);
break;
case MENU_PLACEMENT.RIGHT:
eventPosY = this.options.y - Math.floor(menuDimensions.height / 2);
break;
case MENU_PLACEMENT.TOP_LEFT:
eventPosX = this.options.x - menuDimensions.width;
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.TOP_RIGHT:
eventPosY = this.options.y - menuDimensions.height;
break;
case MENU_PLACEMENT.BOTTOM_LEFT:
eventPosX = this.options.x - menuDimensions.width;
break;
case MENU_PLACEMENT.BOTTOM_RIGHT:
break;
}
return {
x: eventPosX,
y: eventPosY
};
},
/**
* @private
*/
_preventMenuOverflow(menuPosition, menuDimensions) {
let { x: eventPosX, y: eventPosY } = menuPosition;
let overflowX = eventPosX + menuDimensions.width - document.body.clientWidth;
let overflowY = eventPosY + menuDimensions.height - document.body.clientHeight;
if (overflowX > 0) {
eventPosX = eventPosX - overflowX;
}
if (overflowY > 0) {
eventPosY = eventPosY - overflowY;
}
if (eventPosX < 0) {
eventPosX = 0;
}
if (eventPosY < 0) {
eventPosY = 0;
}
return {
x: eventPosX,
y: eventPosY
};
}
},
mounted() {
this.$nextTick(() => {
const position = this._calculatePopupPosition(this.$el);
this.top = position.y;
this.left = position.x;
});
},
data() {
return {
top: '0px',
left: '0px'
};
},
computed: {
styleObject() {
return {
top: `${this.top}px`,
left: `${this.left}px`
};
}
}
};

View File

@@ -159,6 +159,9 @@ class InMemorySearchProvider {
return pendingQuery.promise;
}
/**
* @private
*/
#localQueryFallBack({ queryId, searchType, query, maxResults }) {
if (searchType === this.searchTypes.OBJECTS) {
return this.localSearchForObjects(queryId, query, maxResults);

View File

@@ -96,12 +96,26 @@ class MutableDomainObject {
//Emit events specific to properties affected
let parentPropertiesList = path.split('.');
for (let index = parentPropertiesList.length; index > 0; index--) {
let pathToThisProperty = parentPropertiesList.slice(0, index);
let parentPropertyPath = parentPropertiesList.slice(0, index).join('.');
this._globalEventEmitter.emit(
qualifiedEventName(this, parentPropertyPath),
_.get(this, parentPropertyPath),
_.get(oldModel, parentPropertyPath)
);
const lastPathElement = parentPropertiesList[index - 1];
// Also emit an event for the array whose element has changed so developers do not need to listen to every element of the array.
if (lastPathElement.endsWith(']')) {
const arrayPathElement = lastPathElement.substring(0, lastPathElement.lastIndexOf('['));
pathToThisProperty[index - 1] = arrayPathElement;
const pathToArrayString = pathToThisProperty.join('.');
this._globalEventEmitter.emit(
qualifiedEventName(this, pathToArrayString),
_.get(this, pathToArrayString),
_.get(oldModel, pathToArrayString)
);
}
}
//TODO: Emit events for listeners of child properties when parent changes.

View File

@@ -1,10 +1,10 @@
import DialogComponent from './components/DialogComponent.vue';
import Overlay from './Overlay';
import Vue from 'vue';
import mount from 'utils/mount';
class Dialog extends Overlay {
constructor({ iconClass, message, title, hint, timestamp, ...options }) {
let component = new Vue({
const { vNode, destroy } = mount({
components: {
DialogComponent: DialogComponent
},
@@ -16,17 +16,17 @@ class Dialog extends Overlay {
timestamp
},
template: '<dialog-component></dialog-component>'
}).$mount();
});
super({
element: component.$el,
element: vNode.el,
size: 'fit',
dismissable: false,
...options
});
this.once('destroy', () => {
component.$destroy();
destroy();
});
}
}

View File

@@ -1,6 +1,6 @@
import OverlayComponent from './components/OverlayComponent.vue';
import EventEmitter from 'EventEmitter';
import Vue from 'vue';
import mount from 'utils/mount';
const cssClasses = {
large: 'l-overlay-large',
@@ -28,18 +28,25 @@ class Overlay extends EventEmitter {
this.autoHide = autoHide;
this.dismissable = dismissable !== false;
this.component = new Vue({
components: {
OverlayComponent: OverlayComponent
const { destroy } = mount(
{
components: {
OverlayComponent: OverlayComponent
},
provide: {
dismiss: this.notifyAndDismiss.bind(this),
element,
buttons,
dismissable: this.dismissable
},
template: '<overlay-component></overlay-component>'
},
provide: {
dismiss: this.notifyAndDismiss.bind(this),
element,
buttons,
dismissable: this.dismissable
},
template: '<overlay-component></overlay-component>'
});
{
element: this.container
}
);
this.destroy = destroy;
if (onDestroy) {
this.once('destroy', onDestroy);
@@ -53,7 +60,7 @@ class Overlay extends EventEmitter {
dismiss() {
this.emit('destroy');
document.body.removeChild(this.container);
this.component.$destroy();
this.destroy();
}
//Ensures that any callers are notified that the overlay is dismissed
@@ -67,7 +74,6 @@ class Overlay extends EventEmitter {
**/
show() {
document.body.appendChild(this.container);
this.container.appendChild(this.component.$mount().$el);
}
}

View File

@@ -1,9 +1,8 @@
import ProgressDialogComponent from './components/ProgressDialogComponent.vue';
import Overlay from './Overlay';
import Vue from 'vue';
import mount from 'utils/mount';
let component;
class ProgressDialog extends Overlay {
constructor({
progressPerc,
@@ -15,7 +14,7 @@ class ProgressDialog extends Overlay {
timestamp,
...options
}) {
component = new Vue({
const { vNode, destroy } = mount({
components: {
ProgressDialogComponent: ProgressDialogComponent
},
@@ -35,17 +34,18 @@ class ProgressDialog extends Overlay {
};
},
template: '<progress-dialog-component :model="model"></progress-dialog-component>'
}).$mount();
});
component = vNode.componentInstance;
super({
element: component.$el,
element: vNode.el,
size: 'fit',
dismissable: false,
...options
});
this.once('destroy', () => {
component.$destroy();
destroy();
});
}

View File

@@ -22,7 +22,7 @@
import SelectionComponent from './components/SelectionComponent.vue';
import Overlay from './Overlay';
import Vue from 'vue';
import mount from 'utils/mount';
class Selection extends Overlay {
constructor({
@@ -34,7 +34,7 @@ class Selection extends Overlay {
currentSelection,
...options
}) {
let component = new Vue({
const { vNode, destroy } = mount({
components: {
SelectionComponent: SelectionComponent
},
@@ -47,7 +47,9 @@ class Selection extends Overlay {
currentSelection
},
template: '<selection-component></selection-component>'
}).$mount();
});
const component = vNode.componentInstance;
super({
element: component.$el,
@@ -59,7 +61,7 @@ class Selection extends Overlay {
});
this.once('destroy', () => {
component.$destroy();
destroy();
});
}
}

View File

@@ -22,7 +22,7 @@
import TooltipComponent from './components/TooltipComponent.vue';
import EventEmitter from 'EventEmitter';
import Vue from 'vue';
import mount from 'utils/mount';
class Tooltip extends EventEmitter {
constructor(
@@ -34,9 +34,7 @@ class Tooltip extends EventEmitter {
) {
super();
this.container = document.createElement('div');
this.component = new Vue({
const { vNode, destroy } = mount({
components: {
TooltipComponent: TooltipComponent
},
@@ -48,6 +46,9 @@ class Tooltip extends EventEmitter {
template: '<tooltip-component toolTipText="toolTipText"></tooltip-component>'
});
this.component = vNode.componentInstance;
this._destroy = destroy;
this.isActive = null;
}
@@ -55,8 +56,7 @@ class Tooltip extends EventEmitter {
if (!this.isActive) {
return;
}
document.body.removeChild(this.container);
this.component.$destroy();
this._destroy();
this.isActive = false;
}
@@ -64,8 +64,7 @@ class Tooltip extends EventEmitter {
* @private
**/
show() {
document.body.appendChild(this.container);
this.container.appendChild(this.component.$mount().$el);
document.body.appendChild(this.component.$el);
this.isActive = true;
}
}

View File

@@ -1,5 +1,7 @@
.c-tooltip-wrapper {
max-width: 200px;
height: auto;
width: auto;
padding: $interiorMargin;
}

View File

@@ -21,13 +21,16 @@
*****************************************************************************/
import EventEmitter from 'EventEmitter';
import { markRaw } from 'vue';
export default class LADTableConfiguration extends EventEmitter {
constructor(domainObject, openmct) {
super();
this.domainObject = domainObject;
this.openmct = openmct;
// Prevent Vue from making this a Proxy, otherwise
// it cannot access any private methods (like #mutate()).
this.openmct = markRaw(openmct);
this.objectMutated = this.objectMutated.bind(this);
this.unlistenFromMutation = openmct.objects.observe(

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import LADTableConfigurationComponent from './components/LADTableConfiguration.vue';
import Vue from 'vue';
import mount from 'utils/mount';
export default function LADTableConfigurationViewProvider(openmct) {
return {
@@ -37,28 +37,34 @@ export default function LADTableConfigurationViewProvider(openmct) {
return object?.type === 'LadTable' || object?.type === 'LadTableSet';
},
view(selection) {
let component;
let _destroy = null;
return {
show(element) {
component = new Vue({
el: element,
components: {
LADTableConfiguration: LADTableConfigurationComponent
const { destroy } = mount(
{
el: element,
components: {
LADTableConfiguration: LADTableConfigurationComponent
},
provide: {
openmct
},
template: '<LADTableConfiguration />'
},
provide: {
openmct
},
template: '<LADTableConfiguration />'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
priority() {
return 1;
},
destroy() {
if (component) {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};

View File

@@ -22,38 +22,47 @@
import LadTable from './components/LADTable.vue';
import LADTableConfiguration from './LADTableConfiguration';
import Vue from 'vue';
import mount from 'utils/mount';
export default class LADTableView {
constructor(openmct, domainObject, objectPath) {
this.openmct = openmct;
this.domainObject = domainObject;
this.objectPath = objectPath;
this.component = undefined;
this.component = null;
this._destroy = null;
}
show(element) {
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
this.component = new Vue({
el: element,
components: {
LadTable
const { vNode, destroy } = mount(
{
el: element,
components: {
LadTable
},
provide: {
openmct: this.openmct,
currentView: this,
ladTableConfiguration
},
data: () => {
return {
domainObject: this.domainObject,
objectPath: this.objectPath
};
},
template:
'<lad-table ref="ladTable" :domain-object="domainObject" :object-path="objectPath"></lad-table>'
},
provide: {
openmct: this.openmct,
currentView: this,
ladTableConfiguration
},
data: () => {
return {
domainObject: this.domainObject,
objectPath: this.objectPath
};
},
template:
'<lad-table ref="ladTable" :domain-object="domainObject" :object-path="objectPath"></lad-table>'
});
{
app: this.openmct.app,
element
}
);
this.component = vNode.componentInstance;
this._destroy = destroy;
}
getViewContext() {
@@ -64,8 +73,9 @@ export default class LADTableView {
return this.component.$refs.ladTable.getViewContext();
}
destroy(element) {
this.component.$destroy();
this.component = undefined;
destroy() {
if (this._destroy) {
this._destroy();
}
}
}

View File

@@ -22,37 +22,46 @@
import LadTableSet from './components/LadTableSet.vue';
import LADTableConfiguration from './LADTableConfiguration';
import Vue from 'vue';
import mount from 'utils/mount';
export default class LadTableSetView {
constructor(openmct, domainObject, objectPath) {
this.openmct = openmct;
this.domainObject = domainObject;
this.objectPath = objectPath;
this.component = undefined;
this._destroy = null;
this.component = null;
}
show(element) {
let ladTableConfiguration = new LADTableConfiguration(this.domainObject, this.openmct);
this.component = new Vue({
el: element,
components: {
LadTableSet
const { vNode, destroy } = mount(
{
el: element,
components: {
LadTableSet
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
currentView: this,
ladTableConfiguration
},
data: () => {
return {
domainObject: this.domainObject
};
},
template: '<lad-table-set ref="ladTableSet" :domain-object="domainObject"></lad-table-set>'
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
currentView: this,
ladTableConfiguration
},
data: () => {
return {
domainObject: this.domainObject
};
},
template: '<lad-table-set ref="ladTableSet" :domain-object="domainObject"></lad-table-set>'
});
{
app: this.openmct.app,
element
}
);
this._destroy = destroy;
this.component = vNode.componentInstance;
}
getViewContext() {
@@ -63,8 +72,9 @@ export default class LadTableSetView {
return this.component.$refs.ladTableSet.getViewContext();
}
destroy(element) {
this.component.$destroy();
this.component = undefined;
destroy() {
if (this._destroy) {
this._destroy();
}
}
}

View File

@@ -190,7 +190,7 @@ export default {
this.previewAction = new PreviewAction(this.openmct);
this.previewAction.on('isVisible', this.togglePreviewState);
},
destroyed() {
unmounted() {
this.openmct.time.off('timeSystem', this.updateTimeSystem);
this.telemetryCollection.off('add', this.setLatestValues);
this.telemetryCollection.off('clear', this.resetValues);

View File

@@ -49,7 +49,7 @@
</template>
<script>
import Vue from 'vue';
import Vue, { toRaw } from 'vue';
import LadRow from './LADRow.vue';
import StalenessUtils from '@/utils/staleness';
@@ -139,7 +139,7 @@ export default {
);
this.initializeViewActions();
},
destroyed() {
unmounted() {
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
this.composition.off('add', this.addItem);
@@ -191,7 +191,7 @@ export default {
reorder(reorderPlan) {
const oldItems = this.items.slice();
reorderPlan.forEach((reorderEvent) => {
this.$set(this.items, reorderEvent.newIndex, oldItems[reorderEvent.oldIndex]);
this.items[reorderEvent.newIndex] = oldItems[reorderEvent.oldIndex];
});
},
metadataHasUnits(valueMetadatas) {
@@ -230,7 +230,7 @@ export default {
};
},
toggleFixedLayout() {
const config = structuredClone(this.configuration);
const config = structuredClone(toRaw(this.configuration));
config.isFixedLayout = !this.configuration.isFixedLayout;
this.ladTableConfiguration.updateConfiguration(config);

View File

@@ -87,7 +87,7 @@ export default {
this.composition.load();
},
destroyed() {
unmounted() {
this.ladTableConfiguration.destroy();
this.openmct.editor.off('isEditing', this.toggleEdit);
@@ -126,7 +126,7 @@ export default {
ladTable.domainObject = domainObject;
ladTable.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.$set(this.ladTelemetryObjects, ladTable.key, []);
this.ladTelemetryObjects[ladTable.key] = [];
this.ladTableObjects.push(ladTable);
const composition = this.openmct.composition.get(ladTable.domainObject);
@@ -165,7 +165,7 @@ export default {
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
telemetryObjects.push(telemetryObject);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
this.shouldShowUnitsCheckbox();
};
@@ -179,7 +179,7 @@ export default {
);
telemetryObjects.splice(index, 1);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
this.shouldShowUnitsCheckbox();
};
@@ -220,7 +220,7 @@ export default {
}
if (showUnitsCheckbox && this.headers.units === undefined) {
this.$set(this.headers, 'units', 'Units');
this.headers.units = 'Units';
}
if (!showUnitsCheckbox && this.headers?.units) {

View File

@@ -33,8 +33,8 @@
</tr>
</thead>
<tbody>
<template v-for="ladTable in ladTableObjects">
<tr :key="ladTable.key" class="c-table__group-header js-lad-table-set__table-headers">
<template v-for="ladTable in ladTableObjects" :key="ladTable.key">
<tr class="c-table__group-header js-lad-table-set__table-headers">
<td colspan="10">
{{ ladTable.domainObject.name }}
</td>
@@ -125,7 +125,7 @@ export default {
this.stalenessSubscription = {};
},
destroyed() {
unmounted() {
this.ladTableConfiguration.off('change', this.handleConfigurationChange);
this.composition.off('add', this.addLadTable);
this.composition.off('remove', this.removeLadTable);
@@ -147,7 +147,7 @@ export default {
ladTable.key = this.openmct.objects.makeKeyString(domainObject.identifier);
ladTable.objectPath = [domainObject, ...this.objectPath];
this.$set(this.ladTelemetryObjects, ladTable.key, []);
this.ladTelemetryObjects[ladTable.key] = [];
this.ladTableObjects.push(ladTable);
let composition = this.openmct.composition.get(ladTable.domainObject);
@@ -201,7 +201,7 @@ export default {
const telemetryObjects = this.ladTelemetryObjects[ladTable.key];
telemetryObjects.push(telemetryObject);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
this.stalenessSubscription[combinedKey] = {};
this.stalenessSubscription[combinedKey].stalenessUtils = new StalenessUtils(
@@ -236,7 +236,7 @@ export default {
this.unwatchStaleness(combinedKey);
telemetryObjects.splice(index, 1);
this.$set(this.ladTelemetryObjects, ladTable.key, telemetryObjects);
this.ladTelemetryObjects[ladTable.key] = telemetryObjects;
};
},
unwatchStaleness(combinedKey) {

View File

@@ -84,7 +84,7 @@ define([
rowCount: 'reflow'
},
template: autoflowTemplate,
destroyed: function () {
unmounted: function () {
controller.destroy();
if (interval) {
@@ -109,7 +109,7 @@ define([
});
}
AutoflowTabularView.prototype = Object.create(VueView.prototype);
AutoflowTabularView.prototype = Object.create(VueView.default.prototype);
return AutoflowTabularView;
});

View File

@@ -20,15 +20,15 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['vue'], function (Vue) {
function VueView(options) {
const vm = new Vue(options);
import mount from 'utils/mount';
export default function () {
return function VueView(options) {
const { vNode, destroy } = mount(options);
this.show = function (container) {
container.appendChild(vm.$mount().$el);
container.appendChild(vNode.el);
};
this.destroy = vm.$destroy.bind(vm);
}
return VueView;
});
this.destroy = destroy;
};
}

View File

@@ -93,7 +93,7 @@ export default {
});
this.registerListeners();
},
beforeDestroy() {
beforeUnmount() {
if (this.plotResizeObserver) {
this.plotResizeObserver.unobserve(this.$refs.plotWrapper);
clearTimeout(this.resizeTimer);

View File

@@ -83,7 +83,7 @@ export default {
this.refreshData
);
},
beforeDestroy() {
beforeUnmount() {
this.stopFollowingTimeContext();
this.removeAllSubscriptions();

View File

@@ -22,7 +22,7 @@
import BarGraphView from './BarGraphView.vue';
import { BAR_GRAPH_KEY, BAR_GRAPH_VIEW } from './BarGraphConstants';
import Vue from 'vue';
import mount from 'utils/mount';
export default function BarGraphViewProvider(openmct) {
function isCompactView(objectPath) {
@@ -44,34 +44,43 @@ export default function BarGraphViewProvider(openmct) {
},
view: function (domainObject, objectPath) {
let component;
let _destroy = null;
let component = null;
return {
show: function (element) {
let isCompact = isCompactView(objectPath);
component = new Vue({
el: element,
components: {
BarGraphView
const { vNode, destroy } = mount(
{
el: element,
components: {
BarGraphView
},
provide: {
openmct,
domainObject,
path: objectPath
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<bar-graph-view ref="graphComponent" :options="options"></bar-graph-view>'
},
provide: {
openmct,
domainObject,
path: objectPath
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<bar-graph-view ref="graphComponent" :options="options"></bar-graph-view>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
component = vNode.componentInstance;
},
destroy: function () {
component.$destroy();
component = undefined;
_destroy();
},
onClearData() {
component.$refs.graphComponent.refreshData();

View File

@@ -1,6 +1,6 @@
import { BAR_GRAPH_INSPECTOR_KEY, BAR_GRAPH_KEY } from '../BarGraphConstants';
import Vue from 'vue';
import BarGraphOptions from './BarGraphOptions.vue';
import mount from 'utils/mount';
export default function BarGraphInspectorViewProvider(openmct) {
return {
@@ -16,29 +16,35 @@ export default function BarGraphInspectorViewProvider(openmct) {
return object && object.type === BAR_GRAPH_KEY;
},
view: function (selection) {
let component;
let _destroy = null;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
BarGraphOptions
const { destroy } = mount(
{
el: element,
components: {
BarGraphOptions
},
provide: {
openmct,
domainObject: selection[0][0].context.item
},
template: '<bar-graph-options></bar-graph-options>'
},
provide: {
openmct,
domainObject: selection[0][0].context.item
},
template: '<bar-graph-options></bar-graph-options>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
priority: function () {
return openmct.priority.HIGH + 1;
},
destroy: function () {
if (component) {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};

View File

@@ -167,7 +167,7 @@ export default {
this.registerListeners();
this.composition.load();
},
beforeDestroy() {
beforeUnmount() {
this.openmct.editor.off('isEditing', this.setEditState);
this.stopListening();
},
@@ -192,7 +192,7 @@ export default {
}
},
addSeries(series, index) {
this.$set(this.plotSeries, this.plotSeries.length, series);
this.plotSeries.push(series);
this.setupOptions();
},
removeSeries(seriesIdentifier) {

View File

@@ -115,7 +115,7 @@ export default {
this.initColorAndName
);
},
beforeDestroy() {
beforeUnmount() {
if (this.removeBarStylesListener) {
this.removeBarStylesListener();
}

View File

@@ -77,7 +77,7 @@ export default {
this.reloadTelemetry
);
},
beforeDestroy() {
beforeUnmount() {
this.stopFollowingTimeContext();
if (!this.composition) {

View File

@@ -22,7 +22,7 @@
import ScatterPlotView from './ScatterPlotView.vue';
import { SCATTER_PLOT_KEY, SCATTER_PLOT_VIEW, TIME_STRIP_KEY } from './scatterPlotConstants.js';
import Vue from 'vue';
import mount from 'utils/mount';
export default function ScatterPlotViewProvider(openmct) {
function isCompactView(objectPath) {
@@ -44,34 +44,42 @@ export default function ScatterPlotViewProvider(openmct) {
},
view: function (domainObject, objectPath) {
let component;
let _destroy = null;
return {
show: function (element) {
let isCompact = isCompactView(objectPath);
component = new Vue({
el: element,
components: {
ScatterPlotView
const isCompact = isCompactView(objectPath);
const { destroy } = mount(
{
el: element,
components: {
ScatterPlotView
},
provide: {
openmct,
domainObject,
path: objectPath
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<scatter-plot-view :options="options"></scatter-plot-view>'
},
provide: {
openmct,
domainObject,
path: objectPath
},
data() {
return {
options: {
compact: isCompact
}
};
},
template: '<scatter-plot-view :options="options"></scatter-plot-view>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
destroy: function () {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};
}

View File

@@ -87,7 +87,10 @@ export default {
watch: {
data: {
immediate: false,
handler: 'updateData'
handler() {
this.updateData();
},
deep: true
}
},
mounted() {
@@ -106,7 +109,7 @@ export default {
this.$refs.plot.on('plotly_relayout', this.zoom);
},
beforeDestroy() {
beforeUnmount() {
if (this.$refs.plot && this.$refs.plot.off) {
this.$refs.plot.off('plotly_relayout', this.zoom);
}

View File

@@ -52,7 +52,7 @@ export default {
mounted() {
this.openmct.editor.on('isEditing', this.setEditState);
},
beforeDestroy() {
beforeUnmount() {
this.openmct.editor.off('isEditing', this.setEditState);
},
methods: {

View File

@@ -64,7 +64,7 @@ export default {
this.registerListeners();
this.composition.load();
},
beforeDestroy() {
beforeUnmount() {
this.stopListening();
},
methods: {
@@ -102,7 +102,7 @@ export default {
}
},
addSeries(series, index) {
this.$set(this.plotSeries, this.plotSeries.length, series);
this.plotSeries.push(series);
this.setAxesLabels();
},
removeSeries(seriesKey) {

View File

@@ -89,7 +89,7 @@ export default {
this.registerListeners();
this.composition.load();
},
beforeDestroy() {
beforeUnmount() {
this.stopListening();
},
methods: {
@@ -135,7 +135,7 @@ export default {
}
},
addSeries(series, index) {
this.$set(this.plotSeries, this.plotSeries.length, series);
this.plotSeries.push(series);
this.setupOptions();
},
removeSeries(seriesIdentifier) {

View File

@@ -1,5 +1,5 @@
import { SCATTER_PLOT_INSPECTOR_KEY, SCATTER_PLOT_KEY } from '../scatterPlotConstants';
import Vue from 'vue';
import mount from 'utils/mount';
import PlotOptions from './PlotOptions.vue';
export default function ScatterPlotInspectorViewProvider(openmct) {
@@ -16,29 +16,34 @@ export default function ScatterPlotInspectorViewProvider(openmct) {
return object && object.type === SCATTER_PLOT_KEY;
},
view: function (selection) {
let component;
let _destroy = null;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
PlotOptions
const { destroy } = mount(
{
el: element,
components: {
PlotOptions
},
provide: {
openmct,
domainObject: selection[0][0].context.item
},
template: '<plot-options></plot-options>'
},
provide: {
openmct,
domainObject: selection[0][0].context.item
},
template: '<plot-options></plot-options>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
priority: function () {
return openmct.priority.HIGH + 1;
},
destroy: function () {
if (component) {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};

View File

@@ -23,8 +23,8 @@ import { SCATTER_PLOT_KEY } from './scatterPlotConstants.js';
import ScatterPlotViewProvider from './ScatterPlotViewProvider';
import ScatterPlotInspectorViewProvider from './inspector/ScatterPlotInspectorViewProvider';
import ScatterPlotCompositionPolicy from './ScatterPlotCompositionPolicy';
import Vue from 'vue';
import ScatterPlotForm from './ScatterPlotForm.vue';
import mount from 'utils/mount';
export default function () {
return function install(openmct) {
@@ -100,24 +100,30 @@ export default function () {
function getScatterPlotFormControl(openmct) {
return {
show(element, model, onChange) {
const rowComponent = new Vue({
el: element,
components: {
ScatterPlotForm
const { vNode } = mount(
{
el: element,
components: {
ScatterPlotForm
},
provide: {
openmct
},
data() {
return {
model,
onChange
};
},
template: `<scatter-plot-form :model="model" @onChange="onChange"></scatter-plot-form>`
},
provide: {
openmct
},
data() {
return {
model,
onChange
};
},
template: `<scatter-plot-form :model="model" @onChange="onChange"></scatter-plot-form>`
});
{
app: openmct.app,
element
}
);
return rowComponent;
return vNode;
}
};
}

View File

@@ -19,39 +19,42 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import ClearDataAction from './ClearDataAction';
import GlobalClearIndicator from './components/globalClearIndicator.vue';
import mount from 'utils/mount';
define(['./components/globalClearIndicator.vue', './ClearDataAction', 'vue'], function (
GlobaClearIndicator,
ClearDataAction,
Vue
) {
return function plugin(appliesToObjects, options = { indicator: true }) {
let installIndicator = options.indicator;
export default function plugin(appliesToObjects, options = { indicator: true }) {
let installIndicator = options.indicator;
appliesToObjects = appliesToObjects || [];
appliesToObjects = appliesToObjects || [];
return function install(openmct) {
if (installIndicator) {
let component = new Vue({
return function install(openmct) {
if (installIndicator) {
const { vNode } = mount(
{
components: {
GlobalClearIndicator: GlobaClearIndicator.default
GlobalClearIndicator
},
provide: {
openmct
},
template: '<GlobalClearIndicator></GlobalClearIndicator>'
});
},
{
app: openmct.app,
element: document.createElement('div')
}
);
let indicator = {
element: component.$mount().$el,
key: 'global-clear-indicator',
priority: openmct.priority.DEFAULT
};
let indicator = {
element: vNode.el,
key: 'global-clear-indicator',
priority: openmct.priority.DEFAULT
};
openmct.indicators.add(indicator);
}
openmct.indicators.add(indicator);
}
openmct.actions.register(new ClearDataAction.default(openmct, appliesToObjects));
};
openmct.actions.register(new ClearDataAction(openmct, appliesToObjects));
};
});
}

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import Clock from './components/Clock.vue';
import Vue from 'vue';
import mount from 'utils/mount';
export default function ClockViewProvider(openmct) {
return {
@@ -33,25 +33,33 @@ export default function ClockViewProvider(openmct) {
},
view: function (domainObject) {
let component;
let _destroy = null;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
Clock
const { destroy } = mount(
{
el: element,
components: {
Clock
},
provide: {
openmct,
domainObject
},
template: '<clock />'
},
provide: {
openmct,
domainObject
},
template: '<clock />'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
destroy: function () {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};
}

View File

@@ -21,18 +21,16 @@
-->
<template>
<div class="l-angular-ov-wrapper">
<div class="u-contents">
<div class="c-clock l-time-display u-style-receiver js-style-receiver">
<div class="c-clock__timezone">
{{ timeZoneAbbr }}
</div>
<div class="c-clock__value">
{{ timeTextValue }}
</div>
<div class="c-clock__ampm">
{{ timeAmPm }}
</div>
<div class="u-contents">
<div class="c-clock l-time-display u-style-receiver js-style-receiver">
<div class="c-clock__timezone">
{{ timeZoneAbbr }}
</div>
<div class="c-clock__value">
{{ timeTextValue }}
</div>
<div class="c-clock__ampm">
{{ timeAmPm }}
</div>
</div>
</div>
@@ -47,13 +45,11 @@ export default {
inject: ['openmct', 'domainObject'],
data() {
return {
configuration: this.domainObject.configuration,
lastTimestamp: this.openmct.time.now()
};
},
computed: {
configuration() {
return this.domainObject.configuration;
},
baseFormat() {
return this.configuration.baseFormat;
},
@@ -85,10 +81,21 @@ export default {
}
},
mounted() {
this.unobserve = this.openmct.objects.observe(
this.domainObject,
'configuration',
(configuration) => {
this.configuration = configuration;
}
);
this.tick = raf(this.tick);
this.openmct.time.on('tick', this.tick);
},
beforeDestroy() {
beforeUnmount() {
if (this.unobserve) {
this.unobserve();
}
this.openmct.time.off('tick', this.tick);
},
methods: {

View File

@@ -50,7 +50,7 @@ export default {
this.openmct.time.on('tick', this.tick);
this.tick(this.timeTextValue);
},
beforeDestroy() {
beforeUnmount() {
this.openmct.time.off('tick', this.tick);
},
methods: {

View File

@@ -24,7 +24,7 @@ import ClockViewProvider from './ClockViewProvider';
import ClockIndicator from './components/ClockIndicator.vue';
import momentTimezone from 'moment-timezone';
import Vue from 'vue';
import mount from 'utils/mount';
export default function ClockPlugin(options) {
return function install(openmct) {
@@ -93,26 +93,33 @@ export default function ClockPlugin(options) {
openmct.objectViews.addProvider(new ClockViewProvider(openmct));
if (options && options.enableClockIndicator === true) {
const clockIndicator = new Vue({
components: {
ClockIndicator
const element = document.createElement('div');
const { vNode } = mount(
{
components: {
ClockIndicator
},
provide: {
openmct
},
data() {
return {
indicatorFormat: CLOCK_INDICATOR_FORMAT
};
},
template: '<ClockIndicator :indicator-format="indicatorFormat" />'
},
provide: {
openmct
},
data() {
return {
indicatorFormat: CLOCK_INDICATOR_FORMAT
};
},
template: '<ClockIndicator :indicator-format="indicatorFormat" />'
});
{
app: openmct.app,
element
}
);
const indicator = {
element: clockIndicator.$mount().$el,
element: vNode.el,
key: 'clock-indicator',
priority: openmct.priority.LOW
};
openmct.indicators.add(indicator);
}

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import ConditionSet from './components/ConditionSet.vue';
import Vue from 'vue';
import mount from 'utils/mount';
const DEFAULT_VIEW_PRIORITY = 100;
@@ -46,35 +46,44 @@ export default class ConditionSetViewProvider {
}
view(domainObject, objectPath) {
let component;
const openmct = this.openmct;
let _destroy = null;
let component = null;
return {
show: (container, isEditing) => {
component = new Vue({
el: container,
components: {
ConditionSet
const { vNode, destroy } = mount(
{
el: container,
components: {
ConditionSet
},
provide: {
openmct: this.openmct,
domainObject,
objectPath
},
data() {
return {
isEditing
};
},
template: '<condition-set :isEditing="isEditing"></condition-set>'
},
provide: {
openmct,
domainObject,
objectPath
},
data() {
return {
isEditing
};
},
template: '<condition-set :isEditing="isEditing"></condition-set>'
});
{
app: this.openmct.app,
element: container
}
);
_destroy = destroy;
component = vNode.componentInstance;
},
onEditModeChange: (isEditing) => {
component.isEditing = isEditing;
},
destroy: () => {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};
}

View File

@@ -270,7 +270,7 @@ export default {
return false;
}
},
destroyed() {
unmounted() {
this.destroy();
},
mounted() {

View File

@@ -122,7 +122,7 @@ export default {
deep: true
}
},
destroyed() {
unmounted() {
this.composition.off('add', this.addTelemetryObject);
this.composition.off('remove', this.removeTelemetryObject);
if (this.conditionManager) {

View File

@@ -154,7 +154,7 @@ export default {
deep: true
}
},
beforeDestroy() {
beforeUnmount() {
this.resetApplied();
},
mounted() {

View File

@@ -229,7 +229,7 @@ export default {
return this.styleableFontItems.length && this.allowEditing;
}
},
destroyed() {
unmounted() {
this.removeListeners();
this.openmct.editor.off('isEditing', this.setEditState);
this.stylesManager.off('styleSelected', this.applyStyleToSelection);
@@ -878,8 +878,8 @@ export default {
const fontSize = hasConsolidatedFontSize ? styles[0].fontSize : NON_SPECIFIC;
const font = hasConsolidatedFont ? styles[0].font : NON_SPECIFIC;
this.$set(this.consolidatedFontStyle, 'fontSize', fontSize);
this.$set(this.consolidatedFontStyle, 'font', font);
this.consolidatedFontStyle.fontSize = fontSize;
this.consolidatedFontStyle.font = font;
}
},
getFontStyle(selectionPath) {
@@ -934,7 +934,7 @@ export default {
}
// sync vue component on font update
this.$set(this.consolidatedFontStyle, property, value);
this.consolidatedFontStyle[property] = value;
},
isLayoutObject(selectionPath) {
const layoutItemType =

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
import ConditionWidgetComponent from './components/ConditionWidget.vue';
import Vue from 'vue';
import mount from 'utils/mount';
export default function ConditionWidget(openmct) {
return {
@@ -35,25 +35,33 @@ export default function ConditionWidget(openmct) {
return domainObject.type === 'conditionWidget';
},
view: function (domainObject) {
let component;
let _destroy = null;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
ConditionWidgetComponent: ConditionWidgetComponent
const { destroy } = mount(
{
el: element,
components: {
ConditionWidgetComponent: ConditionWidgetComponent
},
provide: {
openmct,
domainObject
},
template: '<condition-widget-component></condition-widget-component>'
},
provide: {
openmct,
domainObject
},
template: '<condition-widget-component></condition-widget-component>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
destroy: function (element) {
component.$destroy();
component = undefined;
destroy: function () {
if (_destroy) {
_destroy();
}
}
};
},

View File

@@ -81,7 +81,7 @@ export default {
this.listenToConditionSetChanges();
}
},
beforeDestroy() {
beforeUnmount() {
this.stopListeningToConditionSetChanges();
},
methods: {

View File

@@ -22,30 +22,38 @@
import AlphanumericFormat from './components/AlphanumericFormat.vue';
import Vue from 'vue';
import mount from 'utils/mount';
class AlphanumericFormatView {
constructor(openmct, domainObject, objectPath) {
this.openmct = openmct;
this.domainObject = domainObject;
this.objectPath = objectPath;
this.component = undefined;
this._destroy = null;
this.component = null;
}
show(element) {
this.component = new Vue({
el: element,
name: 'AlphanumericFormat',
components: {
AlphanumericFormat
const { vNode, destroy } = mount(
{
el: element,
components: {
AlphanumericFormat
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
currentView: this
},
template: '<AlphanumericFormat ref="alphanumericFormat" />'
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
currentView: this
},
template: '<alphanumeric-format ref="alphanumericFormat"></alphanumeric-format>'
});
{
app: this.openmct.app,
element
}
);
this.component = vNode.componentInstance;
this._destroy = destroy;
}
getViewContext() {
@@ -61,8 +69,9 @@ class AlphanumericFormatView {
}
destroy() {
this.component.$destroy();
this.component = undefined;
if (this._destroy) {
this._destroy();
}
}
}

View File

@@ -61,7 +61,7 @@ export default {
this.openmct.selection.on('change', this.handleSelection);
this.handleSelection(this.openmct.selection.get());
},
destroyed() {
unmounted() {
this.openmct.editor.off('isEditing', this.toggleEdit);
this.openmct.selection.off('change', this.handleSelection);
},

View File

@@ -115,7 +115,7 @@ export default {
this.initSelect
);
},
destroyed() {
unmounted() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -55,7 +55,7 @@
:grid-size="gridSize"
:init-select="initSelectIndex === index"
:index="index"
:multi-select="selectedLayoutItems.length > 1"
:multi-select="selectedLayoutItems.length > 1 || null"
:is-editing="isEditing"
@contextClick="updateViewContext"
@move="move"
@@ -161,16 +161,14 @@ export default {
selection: [],
showGrid: true,
viewContext: {},
gridDimensions: [0, 0]
gridDimensions: [0, 0],
layoutItems: this.domainObject.configuration.items
};
},
computed: {
gridSize() {
return this.domainObject.configuration.layoutGrid.map(Number);
},
layoutItems() {
return this.domainObject.configuration.items;
},
selectedLayoutItems() {
return this.layoutItems.filter((item) => {
return this.itemIsInCurrentSelection(item);
@@ -223,9 +221,13 @@ export default {
this.composition.load();
this.gridDimensions = [this.$el.offsetWidth, this.$el.scrollHeight];
this.openmct.objects.observe(this.domainObject, 'configuration.items', (items) => {
this.layoutItems = items;
});
this.watchDisplayResize();
},
destroyed: function () {
unmounted: function () {
this.openmct.selection.off('change', this.setSelection);
this.composition.off('add', this.addChild);
this.composition.off('remove', this.removeChild);

View File

@@ -115,7 +115,7 @@ export default {
this.initSelect
);
},
destroyed() {
unmounted() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -118,7 +118,7 @@ export default {
this.initSelect
);
},
destroyed() {
unmounted() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -24,13 +24,13 @@
<div class="l-layout__frame c-frame no-frame c-line-view" :class="[styleClass]" :style="style">
<svg width="100%" height="100%">
<line
class="c-line-view__hover-indicator"
v-bind="linePosition"
class="c-line-view__hover-indicator"
vector-effect="non-scaling-stroke"
/>
<line
class="c-line-view__line"
v-bind="linePosition"
class="c-line-view__line"
:stroke="stroke"
vector-effect="non-scaling-stroke"
/>
@@ -257,7 +257,7 @@ export default {
this.initSelect
);
},
destroyed() {
unmounted() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -133,7 +133,7 @@ export default {
this.openmct.objects.get(this.item.identifier).then(this.setObject);
}
},
beforeDestroy() {
beforeUnmount() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -238,7 +238,7 @@ export default {
this.status = this.openmct.status.get(this.item.identifier);
this.removeStatusListener = this.openmct.status.observe(this.item.identifier, this.setStatus);
},
beforeDestroy() {
beforeUnmount() {
this.removeStatusListener();
if (this.removeSelectable) {

View File

@@ -127,7 +127,7 @@ export default {
this.initSelect
);
},
destroyed() {
unmounted() {
if (this.removeSelectable) {
this.removeSelectable();
}

View File

@@ -17,11 +17,6 @@
flex-direction: column;
overflow: auto;
&__grid-holder,
&__dimensions {
display: none;
}
&__dimensions {
$b: 1px dashed $editDimensionsColor;
border-right: $b;

View File

@@ -1,6 +1,5 @@
.c-frame-edit {
// In Layouts, this is the editing rect and handles
display: none; // Set to display: block in DisplayLayout.vue
pointer-events: none;
@include abs();
border: $editMarqueeBorder;

View File

@@ -40,7 +40,7 @@ export default {
);
this.initObjectStyles();
},
beforeDestroy() {
beforeUnmount() {
if (this.stopListeningObjectStyles) {
this.stopListeningObjectStyles();
}

View File

@@ -26,10 +26,8 @@ import DisplayLayout from './components/DisplayLayout.vue';
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js';
import DisplayLayoutType from './DisplayLayoutType.js';
import DisplayLayoutDrawingObjectTypes from './DrawingObjectTypes.js';
import objectUtils from 'objectUtils';
import Vue from 'vue';
import mount from 'utils/mount';
class DisplayLayoutView {
constructor(openmct, domainObject, objectPath, options) {
@@ -38,31 +36,40 @@ class DisplayLayoutView {
this.objectPath = objectPath;
this.options = options;
this.component = undefined;
this.component = null;
this.app = null;
}
show(container, isEditing) {
this.component = new Vue({
el: container,
components: {
DisplayLayout
const { vNode, destroy } = mount(
{
el: container,
components: {
DisplayLayout
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
options: this.options,
objectUtils,
currentView: this
},
data: () => {
return {
domainObject: this.domainObject,
isEditing
};
},
template:
'<display-layout ref="displayLayout" :domain-object="domainObject" :is-editing="isEditing"></display-layout>'
},
provide: {
openmct: this.openmct,
objectPath: this.objectPath,
options: this.options,
objectUtils,
currentView: this
},
data: () => {
return {
domainObject: this.domainObject,
isEditing
};
},
template:
'<display-layout ref="displayLayout" :domain-object="domainObject" :is-editing="isEditing"></display-layout>'
});
{
app: this.openmct.app,
element: container
}
);
this._destroy = destroy;
this.component = vNode.componentInstance;
}
getViewContext() {
@@ -95,8 +102,9 @@ class DisplayLayoutView {
}
destroy() {
this.component.$destroy();
this.component = undefined;
if (this._destroy) {
this._destroy();
}
}
}

View File

@@ -22,7 +22,7 @@
import FaultManagementInspector from './FaultManagementInspector.vue';
import Vue from 'vue';
import mount from 'utils/mount';
import { FAULT_MANAGEMENT_INSPECTOR, FAULT_MANAGEMENT_TYPE } from './constants';
@@ -41,28 +41,34 @@ export default function FaultManagementInspectorViewProvider(openmct) {
return object && object.type === FAULT_MANAGEMENT_TYPE;
},
view: (selection) => {
let component;
let _destroy = null;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
FaultManagementInspector
const { destroy } = mount(
{
el: element,
components: {
FaultManagementInspector
},
provide: {
openmct
},
template: '<FaultManagementInspector></FaultManagementInspector>'
},
provide: {
openmct
},
template: '<FaultManagementInspector></FaultManagementInspector>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
priority: function () {
return openmct.priority.HIGH + 1;
},
destroy: function () {
if (component) {
component.$destroy();
component = undefined;
if (_destroy) {
_destroy();
}
}
};

View File

@@ -167,7 +167,7 @@ export default {
},
toggleSelected({ fault, selected = false }) {
if (selected) {
this.$set(this.selectedFaults, fault.id, fault);
this.selectedFaults[fault.id] = fault;
} else {
this.$delete(this.selectedFaults, fault.id);
}

View File

@@ -41,7 +41,7 @@ export default {
mounted() {
this.unsubscribe = this.openmct.faults.subscribe(this.domainObject, this.updateFault);
},
beforeDestroy() {
beforeUnmount() {
if (this.unsubscribe) {
this.unsubscribe();
}
@@ -53,7 +53,7 @@ export default {
} else if (type === FAULT_MANAGEMENT_ALARMS) {
this.faultsList.forEach((faultValue, i) => {
if (fault.id === faultValue.id) {
this.$set(this.faultsList, i, fault);
this.faultsList[i] = fault;
}
});
}

View File

@@ -22,7 +22,7 @@
import FaultManagementView from './FaultManagementView.vue';
import { FAULT_MANAGEMENT_TYPE, FAULT_MANAGEMENT_VIEW } from './constants';
import Vue from 'vue';
import mount from 'utils/mount';
export default class FaultManagementViewProvider {
constructor(openmct) {
@@ -39,30 +39,34 @@ export default class FaultManagementViewProvider {
}
view(domainObject) {
let component;
const openmct = this.openmct;
let _destroy = null;
return {
show: (element) => {
component = new Vue({
el: element,
components: {
FaultManagementView
const { destroy } = mount(
{
el: element,
components: {
FaultManagementView
},
provide: {
openmct,
domainObject
},
template: '<FaultManagementView></FaultManagementView>'
},
provide: {
openmct,
domainObject
},
template: '<FaultManagementView></FaultManagementView>'
});
{
app: openmct.app,
element
}
);
_destroy = destroy;
},
destroy: () => {
if (!component) {
return;
if (_destroy) {
_destroy();
}
component.$destroy();
component = undefined;
}
};
}

View File

@@ -20,59 +20,70 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['./components/FiltersView.vue', 'vue'], function (FiltersView, Vue) {
function FiltersInspectorViewProvider(openmct, supportedObjectTypesArray) {
import mount from 'utils/mount';
import FiltersView from './components/FiltersView.vue';
const FILTERS_INSPECTOR_KEY = 'filters-inspector';
export default class FiltersInspectorViewProvider {
constructor(openmct, supportedObjectTypesArray) {
this.openmct = openmct;
this.supportedObjectTypesArray = supportedObjectTypesArray;
this.key = FILTERS_INSPECTOR_KEY;
this.name = 'Filters';
}
canView(selection) {
const domainObject = selection?.[0]?.[0]?.context?.item;
return (
domainObject && this.supportedObjectTypesArray.some((type) => domainObject.type === type)
);
}
view(selection) {
let openmct = this.openmct;
let _destroy = null;
const domainObject = selection?.[0]?.[0]?.context?.item;
return {
key: 'filters-inspector',
name: 'Filters',
canView: function (selection) {
const domainObject = selection?.[0]?.[0]?.context?.item;
return domainObject && supportedObjectTypesArray.some((type) => domainObject.type === type);
},
view: function (selection) {
let component;
const domainObject = selection?.[0]?.[0]?.context?.item;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
FiltersView: FiltersView.default
},
provide: {
openmct
},
template: '<filters-view></filters-view>'
});
show: function (element) {
const { destroy } = mount(
{
el: element,
components: {
FiltersView
},
provide: {
openmct: openmct
},
template: '<filters-view></filters-view>'
},
showTab: function (isEditing) {
if (isEditing) {
return true;
}
const metadata = openmct.telemetry.getMetadata(domainObject);
const metadataWithFilters = metadata
? metadata.valueMetadatas.filter((value) => value.filters)
: [];
return metadataWithFilters.length;
},
priority: function () {
return openmct.priority.DEFAULT;
},
destroy: function () {
if (component) {
component.$destroy();
component = undefined;
}
{
app: openmct.app,
element
}
};
);
_destroy = destroy;
},
showTab: function (isEditing) {
if (isEditing) {
return true;
}
const metadata = openmct.telemetry.getMetadata(domainObject);
const metadataWithFilters = metadata
? metadata.valueMetadatas.filter((value) => value.filters)
: [];
return metadataWithFilters.length;
},
priority: function () {
return openmct.priority.DEFAULT;
},
destroy: function () {
if (_destroy) {
_destroy();
}
}
};
}
return FiltersInspectorViewProvider;
});
}

View File

@@ -133,7 +133,7 @@ export default {
mounted() {
this.openmct.editor.on('isEditing', this.toggleIsEditing);
},
beforeDestroy() {
beforeUnmount() {
this.openmct.editor.off('isEditing', this.toggleIsEditing);
},
methods: {

View File

@@ -136,7 +136,7 @@ export default {
this.objectCssClass = type.definition.cssClass;
this.openmct.editor.on('isEditing', this.toggleIsEditing);
},
beforeDestroy() {
beforeUnmount() {
this.openmct.editor.off('isEditing', this.toggleIsEditing);
},
methods: {
@@ -151,32 +151,32 @@ export default {
filterValue[comparator].push(valueName);
} else {
if (filterValue[comparator].length === 1) {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
} else {
filterValue[comparator] = filterValue[comparator].filter((v) => v !== valueName);
}
}
} else {
this.$set(this.updatedFilters[key], comparator, [valueName]);
this.updatedFilters[key][comparator] = [valueName];
}
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
clearFilters(key) {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
updateFiltersWithTextValue(key, comparator, value) {
if (value.trim() === '') {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
} else {
this.$set(this.updatedFilters[key], comparator, value);
this.updatedFilters[key][comparator] = value;
}
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
updateSingleSelection(key, comparator, value) {
this.$set(this.updatedFilters[key], comparator, [value]);
this.updatedFilters[key][comparator] = [value];
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
useGlobalFilter(checked) {

View File

@@ -114,7 +114,7 @@ export default {
this.updateGlobalFilters
);
},
beforeDestroy() {
beforeUnmount() {
this.composition.off('add', this.addChildren);
this.composition.off('remove', this.removeChildren);
this.unobserve();
@@ -136,21 +136,21 @@ export default {
};
if (metadataWithFilters.length) {
this.$set(this.children, keyString, childObject);
this.children[keyString] = childObject;
metadataWithFilters.forEach((metadatum) => {
if (!this.globalFilters[metadatum.key]) {
this.$set(this.globalFilters, metadatum.key, {});
this.globalFilters[metadatum.key] = {};
}
if (!this.globalMetadata[metadatum.key]) {
this.$set(this.globalMetadata, metadatum.key, metadatum);
this.globalMetadata[metadatum.key] = metadatum;
}
if (!hasFiltersWithKeyString) {
if (!this.persistedFilters[keyString]) {
this.$set(this.persistedFilters, keyString, {});
this.$set(this.persistedFilters[keyString], 'useGlobal', true);
this.persistedFilters[keyString] = {};
this.persistedFilters[keyString].useGlobal = true;
mutateFilters = true;
}
@@ -239,10 +239,10 @@ export default {
this.containsField(keyString, key)
) {
if (!this.persistedFilters[keyString][key]) {
this.$set(this.persistedFilters[keyString], key, {});
this.persistedFilters[keyString][key] = {};
}
this.$set(this.persistedFilters[keyString], key, filters[key]);
this.persistedFilters[keyString][key] = filters[key];
mutateFilters = true;
}
});

View File

@@ -101,7 +101,7 @@ export default {
this.expanded = !this.expanded;
},
clearFilters(key) {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
this.$emit('persistGlobalFilters', key, this.updatedFilters);
},
updateFiltersWithSelectedValue(key, comparator, valueName, value) {
@@ -112,26 +112,26 @@ export default {
filterValue[comparator].push(valueName);
} else {
if (filterValue[comparator].length === 1) {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
} else {
filterValue[comparator] = filterValue[comparator].filter((v) => v !== valueName);
}
}
} else {
this.$set(this.updatedFilters[key], comparator, [valueName]);
this.updatedFilters[key][comparator] = [valueName];
}
this.$emit('persistGlobalFilters', key, this.updatedFilters);
},
updateSingleSelection(key, comparator, value) {
this.$set(this.updatedFilters[key], comparator, [value]);
this.updatedFilters[key][comparator] = [value];
this.$emit('persistGlobalFilters', key, this.updatedFilters);
},
updateFiltersWithTextValue(key, comparator, value) {
if (value.trim() === '') {
this.$set(this.updatedFilters, key, {});
this.updatedFilters[key] = {};
} else {
this.$set(this.updatedFilters[key], comparator, value);
this.updatedFilters[key][comparator] = value;
}
this.$emit('persistGlobalFilters', key, this.updatedFilters);

View File

@@ -24,7 +24,7 @@ define(['./FiltersInspectorViewProvider'], function (FiltersInspectorViewProvide
return function plugin(supportedObjectTypesArray) {
return function install(openmct) {
openmct.inspectorViews.addProvider(
new FiltersInspectorViewProvider(openmct, supportedObjectTypesArray)
new FiltersInspectorViewProvider.default(openmct, supportedObjectTypesArray)
);
};
};

View File

@@ -43,9 +43,8 @@
/>
<div class="c-fl-container__frames-holder">
<template v-for="(frame, i) in frames">
<template v-for="(frame, i) in frames" :key="frame.id">
<frame-component
:key="frame.id"
class="c-fl-container__frame"
:frame="frame"
:index="i"
@@ -55,7 +54,6 @@
/>
<drop-hint
:key="'hint-' + i"
class="c-fl-frame__drop-hint"
:index="i"
:allow-drop="allowDrop"
@@ -64,7 +62,6 @@
<resize-handle
v-if="i !== frames.length - 1"
:key="'handle-' + i"
:index="i"
:orientation="rowsLayout ? 'horizontal' : 'vertical'"
:is-editing="isEditing"
@@ -132,7 +129,7 @@ export default {
this.unsubscribeSelection = this.openmct.selection.selectable(this.$el, context, false);
},
beforeDestroy() {
beforeUnmount() {
this.unsubscribeSelection();
},
methods: {

View File

@@ -56,7 +56,7 @@ export default {
document.addEventListener('dragend', this.dragend);
document.addEventListener('drop', this.dragend);
},
destroyed() {
unmounted() {
document.removeEventListener('dragstart', this.dragstart);
document.removeEventListener('dragend', this.dragend);
document.removeEventListener('drop', this.dragend);

View File

@@ -34,7 +34,7 @@
'c-fl--rows': rowsLayout === true
}"
>
<template v-for="(container, index) in containers">
<template v-for="(container, index) in containers" :key="`component-${container.id}`">
<drop-hint
v-if="index === 0 && containers.length > 1"
:key="`hint-top-${container.id}`"
@@ -45,7 +45,6 @@
/>
<container-component
:key="`component-${container.id}`"
class="c-fl__container"
:index="index"
:container="container"
@@ -174,7 +173,7 @@ export default {
this.composition.on('add', this.addFrame);
this.composition.load();
},
beforeDestroy() {
beforeUnmount() {
this.composition.off('remove', this.removeChildObject);
this.composition.off('add', this.addFrame);
},

View File

@@ -114,7 +114,7 @@ export default {
this.dragGhost = document.getElementById('js-fl-drag-ghost');
},
beforeDestroy() {
beforeUnmount() {
if (this.domainObjectPromise) {
this.domainObjectPromise.then(() => {
if (this?.domainObject?.isMutable) {

View File

@@ -56,7 +56,7 @@ export default {
document.addEventListener('dragend', this.unsetDragging);
document.addEventListener('drop', this.unsetDragging);
},
destroyed() {
unmounted() {
document.removeEventListener('dragstart', this.setDragging);
document.removeEventListener('dragend', this.unsetDragging);
document.removeEventListener('drop', this.unsetDragging);

View File

@@ -20,65 +20,82 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(['./components/flexibleLayout.vue', 'vue'], function (FlexibleLayoutComponent, Vue) {
function FlexibleLayoutViewProvider(openmct) {
return {
key: 'flexible-layout',
name: 'FlexibleLayout',
cssClass: 'icon-layout-view',
canView: function (domainObject) {
return domainObject.type === 'flexible-layout';
},
canEdit: function (domainObject) {
return domainObject.type === 'flexible-layout';
},
view: function (domainObject, objectPath) {
let component;
import mount from 'utils/mount';
import FlexibleLayoutComponent from './components/flexibleLayout.vue';
return {
show: function (element, isEditing) {
component = new Vue({
el: element,
components: {
FlexibleLayoutComponent: FlexibleLayoutComponent.default
},
provide: {
openmct,
objectPath,
layoutObject: domainObject
},
data() {
return {
isEditing: isEditing
};
},
template:
'<flexible-layout-component ref="flexibleLayout" :isEditing="isEditing"></flexible-layout-component>'
});
const FLEXIBLE_LAYOUT_KEY = 'flexible-layout';
export default class FlexibleLayoutViewProvider {
constructor(openmct) {
this.openmct = openmct;
this.key = FLEXIBLE_LAYOUT_KEY;
this.name = 'Flexible Layout';
this.cssClass = 'icon-layout-view';
this.destroy = null;
}
canView(domainObject) {
return domainObject.type === FLEXIBLE_LAYOUT_KEY;
}
canEdit(domainObject) {
return domainObject.type === FLEXIBLE_LAYOUT_KEY;
}
view(domainObject, objectPath) {
let openmct = this.openmct;
let _destroy = null;
let component = null;
return {
show: function (element, isEditing) {
const { vNode, destroy } = mount(
{
el: element,
components: {
FlexibleLayoutComponent
},
provide: {
openmct: openmct,
objectPath,
layoutObject: domainObject
},
data() {
return {
isEditing: isEditing
};
},
template:
'<flexible-layout-component ref="flexibleLayout" :isEditing="isEditing"></flexible-layout-component>'
},
getSelectionContext: function () {
return {
item: domainObject,
addContainer: component.$refs.flexibleLayout.addContainer,
deleteContainer: component.$refs.flexibleLayout.deleteContainer,
deleteFrame: component.$refs.flexibleLayout.deleteFrame,
type: 'flexible-layout'
};
},
onEditModeChange: function (isEditing) {
component.isEditing = isEditing;
},
destroy: function (element) {
component.$destroy();
component = undefined;
{
app: openmct.app,
element
}
);
component = vNode.componentInstance;
_destroy = destroy;
},
getSelectionContext: function () {
return {
item: domainObject,
addContainer: component.$refs.flexibleLayout.addContainer,
deleteContainer: component.$refs.flexibleLayout.deleteContainer,
deleteFrame: component.$refs.flexibleLayout.deleteFrame,
type: 'flexible-layout'
};
},
priority: function () {
return 1;
onEditModeChange: function (isEditing) {
component.isEditing = isEditing;
},
destroy: function (element) {
if (_destroy) {
_destroy();
component = null;
}
}
};
}
return FlexibleLayoutViewProvider;
});
priority() {
return 1;
}
}

View File

@@ -27,7 +27,7 @@ define(['./flexibleLayoutViewProvider', './utils/container', './toolbarProvider'
) {
return function plugin() {
return function install(openmct) {
openmct.objectViews.addProvider(new FlexibleLayoutViewProvider(openmct));
openmct.objectViews.addProvider(new FlexibleLayoutViewProvider.default(openmct));
openmct.types.addType('flexible-layout', {
name: 'Flexible Layout',

View File

@@ -19,50 +19,51 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import GridViewComponent from './components/GridView.vue';
import { ALLOWED_FOLDER_TYPES } from './constants.js';
import mount from 'utils/mount';
define(['./components/GridView.vue', './constants.js', 'vue'], function (
GridViewComponent,
constants,
Vue
) {
function FolderGridView(openmct) {
const ALLOWED_FOLDER_TYPES = constants.ALLOWED_FOLDER_TYPES;
export default class FolderGridView {
constructor(openmct) {
this.openmct = openmct;
this.key = 'grid';
this.name = 'Grid View';
this.cssClass = 'icon-thumbs-strip';
}
canView(domainObject) {
return ALLOWED_FOLDER_TYPES.includes(domainObject.type);
}
view(domainObject) {
return {
key: 'grid',
name: 'Grid View',
cssClass: 'icon-thumbs-strip',
canView: function (domainObject) {
return ALLOWED_FOLDER_TYPES.includes(domainObject.type);
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
gridViewComponent: GridViewComponent.default
},
provide: {
openmct,
domainObject
},
template: '<grid-view-component></grid-view-component>'
});
show: (element) => {
const { destroy } = mount(
{
components: {
GridViewComponent
},
provide: {
openmct: this.openmct,
domainObject
},
template: '<GridViewComponent></GridViewComponent>'
},
destroy: function (element) {
component.$destroy();
component = undefined;
{
app: this.openmct.app,
element
}
};
);
this._destroy = destroy;
},
priority: function () {
return 1;
destroy: () => {
if (this._destroy) {
this._destroy();
}
}
};
}
return FolderGridView;
});
priority() {
return 1;
}
}

View File

@@ -19,52 +19,54 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import mount from 'utils/mount';
import ListViewComponent from './components/ListView.vue';
import Moment from 'moment';
import { ALLOWED_FOLDER_TYPES } from './constants.js';
define(['./components/ListView.vue', './constants.js', 'vue', 'moment'], function (
ListViewComponent,
constants,
Vue,
Moment
) {
function FolderListView(openmct) {
const ALLOWED_FOLDER_TYPES = constants.ALLOWED_FOLDER_TYPES;
export default class FolderListView {
constructor(openmct) {
this.openmct = openmct;
this.key = 'list-view';
this.name = 'List View';
this.cssClass = 'icon-list-view';
}
canView(domainObject) {
return ALLOWED_FOLDER_TYPES.includes(domainObject.type);
}
view(domainObject) {
return {
key: 'list-view',
name: 'List View',
cssClass: 'icon-list-view',
canView: function (domainObject) {
return ALLOWED_FOLDER_TYPES.includes(domainObject.type);
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
el: element,
components: {
listViewComponent: ListViewComponent.default
},
provide: {
openmct,
domainObject,
Moment
},
template: '<list-view-component></list-view-component>'
});
show: (element) => {
const { destroy } = mount(
{
el: element,
components: {
ListViewComponent
},
provide: {
openmct: this.openmct,
domainObject,
Moment
},
template: '<ListViewComponent></ListViewComponent>'
},
destroy: function (element) {
component.$destroy();
component = undefined;
{
app: this.openmct.app,
element
}
};
);
this._destroy = destroy;
},
priority: function () {
return 1;
destroy: () => {
if (this._destroy) {
this._destroy();
}
}
};
}
return FolderListView;
});
priority() {
return 1;
}
}

View File

@@ -21,6 +21,7 @@
-->
<template>
<a
ref="root"
class="l-grid-view__item c-grid-item js-folder-child"
:class="[
{
@@ -30,7 +31,7 @@
},
statusClass
]"
@click="navigate"
@click="navigate($event)"
>
<div
class="c-grid-item__type-icon"
@@ -69,7 +70,7 @@ export default {
}
},
methods: {
navigate() {
navigate(_event) {
this.openmct.router.navigate(this.objectLink);
}
}

View File

@@ -21,6 +21,7 @@
-->
<template>
<tr
ref="root"
class="c-list-item js-folder-child"
:class="{
'is-alias': item.isAlias === true

View File

@@ -23,11 +23,10 @@ export default {
this.composition.on('remove', this.remove);
this.composition.load();
},
destroyed() {
beforeUnmount() {
if (!this.composition) {
return;
}
this.composition.off('add', this.add);
this.composition.off('remove', this.remove);
},

View File

@@ -27,7 +27,7 @@ export default {
this.status = this.openmct.status.get(identifier);
this.removeStatusListener = this.openmct.status.observe(identifier, this.setStatus);
},
destroyed() {
unmounted() {
this.removeStatusListener();
}
};

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