mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
6 Commits
refresh-op
...
notebook-s
Author | SHA1 | Date | |
---|---|---|---|
0a820aa869 | |||
7c92b6d206 | |||
395a1caeec | |||
339b315642 | |||
601d59d6bd | |||
c6e2d5a363 |
@ -78,7 +78,7 @@
|
|||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
openmct.install(openmct.plugins.SummaryWidget());
|
openmct.install(openmct.plugins.SummaryWidget());
|
||||||
openmct.install(openmct.plugins.Notebook());
|
openmct.install(openmct.plugins.NotebookSVC());
|
||||||
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
|
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
|
||||||
openmct.install(openmct.plugins.ObjectMigration());
|
openmct.install(openmct.plugins.ObjectMigration());
|
||||||
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
|
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
|
||||||
|
31
src/plugins/notebook-svc/components/embed.vue
Normal file
31
src/plugins/notebook-svc/components/embed.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ne__embed">
|
||||||
|
<div class="c-ne__embed__snap-thumb"
|
||||||
|
v-if="embed.snapshot">
|
||||||
|
<img v-bind:src="embed.snapshot.src">
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embed__info">
|
||||||
|
<div class="c-ne__embed__name">
|
||||||
|
<a class="c-ne__embed__link"
|
||||||
|
:href="objectLink"
|
||||||
|
:class="embed.cssClass">
|
||||||
|
{{embed.name}}
|
||||||
|
</a>
|
||||||
|
<a class="c-ne__embed__context-available icon-arrow-down"></a>
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embed__time" v-if="embed.snapshot">
|
||||||
|
{{formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import objectLinkMixin from '../../../ui/mixins/object-link';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct', 'formatTime'],
|
||||||
|
props: ['embed'],
|
||||||
|
mixins: [objectLinkMixin]
|
||||||
|
}
|
||||||
|
</script>
|
63
src/plugins/notebook-svc/components/entry.vue
Normal file
63
src/plugins/notebook-svc/components/entry.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<li class="c-notebook__entry c-ne has-local-controls"
|
||||||
|
@dragover.prevent
|
||||||
|
@drop.prevent="onTreeItemDrop">
|
||||||
|
<div class="c-ne__time-and-content">
|
||||||
|
<div class="c-ne__time">
|
||||||
|
<span>{{formatTime(entry.createdOn, 'YYYY-MM-DD')}}</span>
|
||||||
|
<span>{{formatTime(entry.createdOn, 'HH:mm:ss')}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__content">
|
||||||
|
<div class="c-ne__text c-input-inline"
|
||||||
|
contenteditable="true"
|
||||||
|
ref="contenteditable"
|
||||||
|
@blur="updateEntry"
|
||||||
|
v-html="entry.text">
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embeds">
|
||||||
|
<notebook-embed
|
||||||
|
v-for="embed in entry.embeds"
|
||||||
|
:key="embed.id"
|
||||||
|
:embed="embed"
|
||||||
|
:objectPath="embed.objectPath">
|
||||||
|
</notebook-embed>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-ne__local-controls--hidden">
|
||||||
|
<button class="c-click-icon c-click-icon--major icon-trash"
|
||||||
|
title="Delete this entry"
|
||||||
|
@click="deleteEntry">
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NotebookEmbed from './embed.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['formatTime'],
|
||||||
|
props: ['entry'],
|
||||||
|
components: {
|
||||||
|
NotebookEmbed
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateEntry(event) {
|
||||||
|
this.$emit('update-entry', this.entry.id, event.target.innerText);
|
||||||
|
},
|
||||||
|
deleteEntry() {
|
||||||
|
this.$emit('delete-entry', this.entry.id);
|
||||||
|
},
|
||||||
|
onTreeItemDrop(event) {
|
||||||
|
this.$emit('drop-embed', this.entry.id, event);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.entry.text && !this.entry.embeds.length) {
|
||||||
|
this.$refs.contenteditable.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
198
src/plugins/notebook-svc/components/notebook.vue
Normal file
198
src/plugins/notebook-svc/components/notebook.vue
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-notebook"
|
||||||
|
@dragover.stop
|
||||||
|
@drop.stop>
|
||||||
|
<div class="c-notebook__head">
|
||||||
|
<search class="c-notebook__search"
|
||||||
|
:value="searchValue"
|
||||||
|
@input="searchEntries"
|
||||||
|
@clear="searchEntries">
|
||||||
|
</search>
|
||||||
|
|
||||||
|
<div class="c-notebook__controls ">
|
||||||
|
<select class="c-notebook__controls__time" v-model="timeFrame">
|
||||||
|
<option value="0" :selected="timeFrame==='0'">Show all</option>
|
||||||
|
<option value="1" :selected="timeFrame==='1'">Last hour</option>
|
||||||
|
<option value="8" :selected="timeFrame==='8'">Last 8 hours</option>
|
||||||
|
<option value="24" :selected="timeFrame==='24'">Last 24 hours</option>
|
||||||
|
</select>
|
||||||
|
<select class="c-notebook__controls__time" v-model="sortOrder">
|
||||||
|
<option value="newest" :selected="sortOrder === 'newest'">Newest first</option>
|
||||||
|
<option value="oldest" :selected="sortOrder === 'oldest'">Oldest first</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-notebook__drag-area icon-plus"
|
||||||
|
@click="newEntry">
|
||||||
|
<span class="c-notebook__drag-area__label">To start a new entry, click here or drag and drop any object</span>
|
||||||
|
</div>
|
||||||
|
<div class="c-notebook__entries">
|
||||||
|
<ul>
|
||||||
|
<entry
|
||||||
|
v-for="entry in entries"
|
||||||
|
:key="entry.id"
|
||||||
|
:entry="entry"
|
||||||
|
@update-entry="persistEntry"
|
||||||
|
@delete-entry="deleteEntry"
|
||||||
|
@drop-embed="addEmbed">
|
||||||
|
</entry>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Search from '../../../ui/components/search.vue';
|
||||||
|
import Entry from './entry.vue';
|
||||||
|
import Moment from 'moment';
|
||||||
|
import searchVue from '../../../ui/components/search.vue';
|
||||||
|
|
||||||
|
function formatTime(unixTime, format) {
|
||||||
|
return Moment(unixTime).format(format)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct', 'providedDomainObject'],
|
||||||
|
components: {
|
||||||
|
Search,
|
||||||
|
Entry
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
formatTime
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
domainObject: this.providedDomainObject,
|
||||||
|
timeFrame: '0',
|
||||||
|
searchValue: '',
|
||||||
|
sortOrder: this.providedDomainObject.configuration.sortOrder
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
searchEntries(value) {
|
||||||
|
this.searchValue = value;
|
||||||
|
},
|
||||||
|
updateDomainObject(domainObject) {
|
||||||
|
this.domainObject = domainObject;
|
||||||
|
},
|
||||||
|
newEntry() {
|
||||||
|
this.searchValue = '';
|
||||||
|
|
||||||
|
let date = Date.now(),
|
||||||
|
entry = {'id': 'entry-' + date, 'createdOn': date, 'embeds':[]},
|
||||||
|
entries = this.domainObject.entries,
|
||||||
|
lastEntry = entries[entries.length - 1];
|
||||||
|
|
||||||
|
if (lastEntry && !lastEntry.text && !lastEntry.embeds.length) {
|
||||||
|
let lastEntryComponent = this.$children.find(entryComponent => {
|
||||||
|
if (entryComponent.entry) {
|
||||||
|
return entryComponent.entry.id === lastEntry.id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
lastEntryComponent.$refs.contenteditable.focus();
|
||||||
|
} else {
|
||||||
|
entries.push(entry);
|
||||||
|
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries', entries);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
findEntry(entryId) {
|
||||||
|
return this.domainObject.entries.findIndex(entry => {
|
||||||
|
return entry.id === entryId;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
persistEntry(entryId, text) {
|
||||||
|
let entryPos = this.findEntry(entryId);
|
||||||
|
|
||||||
|
this.openmct.objects.mutate(this.domainObject, `entries[${entryPos}].text`, text);
|
||||||
|
},
|
||||||
|
deleteEntry(entryId) {
|
||||||
|
let entryPos = this.findEntry(entryId),
|
||||||
|
entries = this.domainObject.entries;
|
||||||
|
|
||||||
|
if (entryPos !== -1) {
|
||||||
|
let dialog = this.openmct.overlays.dialog({
|
||||||
|
iconClass: 'alert',
|
||||||
|
message: 'This action will permanently delete this entry. Do you wish to continue?',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: "Ok",
|
||||||
|
emphasis: true,
|
||||||
|
callback: () => {
|
||||||
|
entries.splice(entryPos, 1);
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries', entries);
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Cancel",
|
||||||
|
callback: () => {
|
||||||
|
dialog.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
applySearch(entries) {
|
||||||
|
return entries.filter((entry) => {
|
||||||
|
if (entry.text.includes(this.searchValue)) {
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addEmbed(entryId, event) {
|
||||||
|
var data = event.dataTransfer.getData('openmct/domain-object-path');
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
var objectPath = JSON.parse(data),
|
||||||
|
domainObject = objectPath[0],
|
||||||
|
domainObjectKey = domainObject.identifier.key,
|
||||||
|
domainObjectType = this.openmct.types.get(domainObject.type),
|
||||||
|
cssClass = domainObjectType && domainObjectType.definition ?
|
||||||
|
domainObjectType.definition.cssClass : 'icon-object-unknown',
|
||||||
|
entryPos = this.findEntry(entryId),
|
||||||
|
currentEntryEmbeds = this.domainObject.entries[entryPos].embeds,
|
||||||
|
newEmbed = {
|
||||||
|
id: '' + Date.now(),
|
||||||
|
domainObject: domainObject,
|
||||||
|
objectPath: objectPath,
|
||||||
|
type: domainObjectKey,
|
||||||
|
cssClass: cssClass,
|
||||||
|
name: domainObject.name,
|
||||||
|
snapshot: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
currentEntryEmbeds.push(newEmbed);
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries[' + entryPos + '].embeds', currentEntryEmbeds);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDrop() {
|
||||||
|
console.log('droped');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
entries() {
|
||||||
|
let entries = [...this.domainObject.entries];
|
||||||
|
|
||||||
|
if (this.searchValue !== '') {
|
||||||
|
entries = this.applySearch(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.sortOrder === 'newest') {
|
||||||
|
return entries.reverse();
|
||||||
|
} else {
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
67
src/plugins/notebook-svc/notebook-view-provider.js
Normal file
67
src/plugins/notebook-svc/notebook-view-provider.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'vue',
|
||||||
|
'./components/notebook.vue'
|
||||||
|
], function (
|
||||||
|
Vue,
|
||||||
|
Notebook
|
||||||
|
) {
|
||||||
|
function NotebookViewProvider(openmct) {
|
||||||
|
return {
|
||||||
|
key: 'notebook',
|
||||||
|
name: 'Notebook',
|
||||||
|
cssClass: 'icon-notebook',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'notebook';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let component;
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: function (element) {
|
||||||
|
component = new Vue({
|
||||||
|
components: {
|
||||||
|
Notebook: Notebook.default
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
openmct,
|
||||||
|
providedDomainObject: domainObject
|
||||||
|
},
|
||||||
|
el: element,
|
||||||
|
template: '<notebook></notebook>'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function (element) {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority: function () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return NotebookViewProvider;
|
||||||
|
});
|
47
src/plugins/notebook-svc/plugin.js
Normal file
47
src/plugins/notebook-svc/plugin.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./notebook-view-provider'
|
||||||
|
], function (
|
||||||
|
NotebookViewProvider
|
||||||
|
) {
|
||||||
|
return function plugin() {
|
||||||
|
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.objectViews.addProvider(new NotebookViewProvider(openmct));
|
||||||
|
|
||||||
|
openmct.types.addType('notebook', {
|
||||||
|
name: "Notebook SVC",
|
||||||
|
creatable: true,
|
||||||
|
description: "Create and save timestamped notes with embedded object snapshots.",
|
||||||
|
cssClass: 'icon-notebook',
|
||||||
|
initialize: function (domainObject) {
|
||||||
|
domainObject.configuration = {
|
||||||
|
sortOrder: 'oldest'
|
||||||
|
};
|
||||||
|
domainObject.entries = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
@ -35,7 +35,7 @@ define([
|
|||||||
|
|
||||||
installed = true;
|
installed = true;
|
||||||
|
|
||||||
openmct.legacyRegistry.register('notebook', {
|
openmct.legacyRegistry.register('notebook-old', {
|
||||||
name: 'Notebook Plugin',
|
name: 'Notebook Plugin',
|
||||||
extensions: {
|
extensions: {
|
||||||
types: [
|
types: [
|
||||||
@ -73,10 +73,10 @@ define([
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
openmct.legacyRegistry.enable('notebook');
|
openmct.legacyRegistry.enable('notebook-old');
|
||||||
|
|
||||||
openmct.objectViews.addProvider({
|
openmct.objectViews.addProvider({
|
||||||
key: 'notebook-vue',
|
key: 'notebook-old',
|
||||||
name: 'Notebook View',
|
name: 'Notebook View',
|
||||||
cssClass: 'icon-notebook',
|
cssClass: 'icon-notebook',
|
||||||
canView: function (domainObject) {
|
canView: function (domainObject) {
|
||||||
|
@ -41,6 +41,7 @@ define([
|
|||||||
'./flexibleLayout/plugin',
|
'./flexibleLayout/plugin',
|
||||||
'./tabs/plugin',
|
'./tabs/plugin',
|
||||||
'./LADTable/plugin',
|
'./LADTable/plugin',
|
||||||
|
'./notebook-svc/plugin',
|
||||||
'./filters/plugin',
|
'./filters/plugin',
|
||||||
'./objectMigration/plugin',
|
'./objectMigration/plugin',
|
||||||
'./goToOriginalAction/plugin',
|
'./goToOriginalAction/plugin',
|
||||||
@ -66,6 +67,7 @@ define([
|
|||||||
FlexibleLayout,
|
FlexibleLayout,
|
||||||
Tabs,
|
Tabs,
|
||||||
LADTable,
|
LADTable,
|
||||||
|
NotebookSVC,
|
||||||
Filters,
|
Filters,
|
||||||
ObjectMigration,
|
ObjectMigration,
|
||||||
GoToOriginalAction,
|
GoToOriginalAction,
|
||||||
@ -159,12 +161,13 @@ define([
|
|||||||
plugins.SummaryWidget = SummaryWidget;
|
plugins.SummaryWidget = SummaryWidget;
|
||||||
plugins.TelemetryMean = TelemetryMean;
|
plugins.TelemetryMean = TelemetryMean;
|
||||||
plugins.URLIndicator = URLIndicatorPlugin;
|
plugins.URLIndicator = URLIndicatorPlugin;
|
||||||
plugins.Notebook = Notebook;
|
// plugins.Notebook = Notebook;
|
||||||
plugins.DisplayLayout = DisplayLayoutPlugin.default;
|
plugins.DisplayLayout = DisplayLayoutPlugin.default;
|
||||||
plugins.FolderView = FolderView;
|
plugins.FolderView = FolderView;
|
||||||
plugins.Tabs = Tabs;
|
plugins.Tabs = Tabs;
|
||||||
plugins.FlexibleLayout = FlexibleLayout;
|
plugins.FlexibleLayout = FlexibleLayout;
|
||||||
plugins.LADTable = LADTable;
|
plugins.LADTable = LADTable;
|
||||||
|
plugins.NotebookSVC = NotebookSVC;
|
||||||
plugins.Filters = Filters;
|
plugins.Filters = Filters;
|
||||||
plugins.ObjectMigration = ObjectMigration.default;
|
plugins.ObjectMigration = ObjectMigration.default;
|
||||||
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
||||||
|
@ -111,7 +111,7 @@ export default {
|
|||||||
event.dataTransfer.setData("openmct/composable-domain-object", JSON.stringify(this.domainObject));
|
event.dataTransfer.setData("openmct/composable-domain-object", JSON.stringify(this.domainObject));
|
||||||
}
|
}
|
||||||
// serialize domain object anyway, because some views can drag-and-drop objects without composition
|
// serialize domain object anyway, because some views can drag-and-drop objects without composition
|
||||||
// (eg. notabook.)
|
// (eg. notebook.)
|
||||||
event.dataTransfer.setData("openmct/domain-object-path", serializedPath);
|
event.dataTransfer.setData("openmct/domain-object-path", serializedPath);
|
||||||
event.dataTransfer.setData(`openmct/domain-object/${keyString}`, this.domainObject);
|
event.dataTransfer.setData(`openmct/domain-object/${keyString}`, this.domainObject);
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ class NotebookSnapshot {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function validateLocation(newParentObj) {
|
function validateLocation(newParentObj) {
|
||||||
return newParentObj.model.type === 'notebook';
|
return newParentObj.model.type === 'notebook' || newParentObj.model.type === 'notebook-svc';
|
||||||
}
|
}
|
||||||
|
|
||||||
return overlayModel;
|
return overlayModel;
|
||||||
|
Reference in New Issue
Block a user