mirror of
https://github.com/nasa/openmct.git
synced 2025-01-30 16:13:53 +00:00
Notebook refactor (#2883)
* Code refactoring per https://github.com/nasa/openmct/issues/2825
This commit is contained in:
parent
505796d9f0
commit
ee60013f45
@ -86,7 +86,7 @@ module.exports = (config) => {
|
|||||||
reports: ['html', 'lcovonly', 'text-summary'],
|
reports: ['html', 'lcovonly', 'text-summary'],
|
||||||
thresholds: {
|
thresholds: {
|
||||||
global: {
|
global: {
|
||||||
lines: 64
|
lines: 65
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -30,7 +30,6 @@ define([
|
|||||||
"./src/controllers/CompositeController",
|
"./src/controllers/CompositeController",
|
||||||
"./src/controllers/ColorController",
|
"./src/controllers/ColorController",
|
||||||
"./src/controllers/DialogButtonController",
|
"./src/controllers/DialogButtonController",
|
||||||
"./src/controllers/SnapshotPreviewController",
|
|
||||||
"./res/templates/controls/autocomplete.html",
|
"./res/templates/controls/autocomplete.html",
|
||||||
"./res/templates/controls/checkbox.html",
|
"./res/templates/controls/checkbox.html",
|
||||||
"./res/templates/controls/datetime.html",
|
"./res/templates/controls/datetime.html",
|
||||||
@ -44,8 +43,7 @@ define([
|
|||||||
"./res/templates/controls/menu-button.html",
|
"./res/templates/controls/menu-button.html",
|
||||||
"./res/templates/controls/dialog.html",
|
"./res/templates/controls/dialog.html",
|
||||||
"./res/templates/controls/radio.html",
|
"./res/templates/controls/radio.html",
|
||||||
"./res/templates/controls/file-input.html",
|
"./res/templates/controls/file-input.html"
|
||||||
"./res/templates/controls/snap-view.html"
|
|
||||||
], function (
|
], function (
|
||||||
MCTForm,
|
MCTForm,
|
||||||
MCTControl,
|
MCTControl,
|
||||||
@ -56,7 +54,6 @@ define([
|
|||||||
CompositeController,
|
CompositeController,
|
||||||
ColorController,
|
ColorController,
|
||||||
DialogButtonController,
|
DialogButtonController,
|
||||||
SnapshotPreviewController,
|
|
||||||
autocompleteTemplate,
|
autocompleteTemplate,
|
||||||
checkboxTemplate,
|
checkboxTemplate,
|
||||||
datetimeTemplate,
|
datetimeTemplate,
|
||||||
@ -70,8 +67,7 @@ define([
|
|||||||
menuButtonTemplate,
|
menuButtonTemplate,
|
||||||
dialogTemplate,
|
dialogTemplate,
|
||||||
radioTemplate,
|
radioTemplate,
|
||||||
fileInputTemplate,
|
fileInputTemplate
|
||||||
snapViewTemplate
|
|
||||||
) {
|
) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -157,10 +153,6 @@ define([
|
|||||||
{
|
{
|
||||||
"key": "file-input",
|
"key": "file-input",
|
||||||
"template": fileInputTemplate
|
"template": fileInputTemplate
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "snap-view",
|
|
||||||
"template": snapViewTemplate
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"controllers": [
|
"controllers": [
|
||||||
@ -194,14 +186,6 @@ define([
|
|||||||
"$scope",
|
"$scope",
|
||||||
"dialogService"
|
"dialogService"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "SnapshotPreviewController",
|
|
||||||
"implementation": SnapshotPreviewController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"openmct"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"components": [
|
"components": [
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2020, 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.
|
|
||||||
-->
|
|
||||||
<span ng-controller="SnapshotPreviewController"
|
|
||||||
class='form-control shell'>
|
|
||||||
<span class='field control {{structure.cssClass}}'>
|
|
||||||
<image
|
|
||||||
class="c-ne__embed__snap-thumb"
|
|
||||||
src="{{imageUrl || structure.src}}"
|
|
||||||
ng-click="previewImage(imageUrl || structure.src)"
|
|
||||||
name="mctControl">
|
|
||||||
</image>
|
|
||||||
<br>
|
|
||||||
<a title="Annotate" class="s-button icon-pencil" ng-click="annotateImage(ngModel, field, imageUrl || structure.src)">
|
|
||||||
<span class="title-label">Annotate</span>
|
|
||||||
</a>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
@ -1,132 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2020, 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(
|
|
||||||
[
|
|
||||||
'painterro'
|
|
||||||
],
|
|
||||||
function (Painterro) {
|
|
||||||
|
|
||||||
function SnapshotPreviewController($scope, openmct) {
|
|
||||||
|
|
||||||
$scope.previewImage = function (imageUrl) {
|
|
||||||
let imageDiv = document.createElement('div');
|
|
||||||
imageDiv.classList = 'image-main s-image-main';
|
|
||||||
imageDiv.style.backgroundImage = `url(${imageUrl})`;
|
|
||||||
|
|
||||||
let previewImageOverlay = openmct.overlays.overlay(
|
|
||||||
{
|
|
||||||
element: imageDiv,
|
|
||||||
size: 'large',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
label: 'Done',
|
|
||||||
callback: function () {
|
|
||||||
previewImageOverlay.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.annotateImage = function (ngModel, field, imageUrl) {
|
|
||||||
$scope.imageUrl = imageUrl;
|
|
||||||
|
|
||||||
let div = document.createElement('div'),
|
|
||||||
painterroInstance = {},
|
|
||||||
save = false;
|
|
||||||
|
|
||||||
div.id = 'snap-annotation';
|
|
||||||
|
|
||||||
let annotateImageOverlay = openmct.overlays.overlay(
|
|
||||||
{
|
|
||||||
element: div,
|
|
||||||
size: 'large',
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
label: 'Cancel',
|
|
||||||
callback: function () {
|
|
||||||
save = false;
|
|
||||||
painterroInstance.save();
|
|
||||||
annotateImageOverlay.dismiss();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Save',
|
|
||||||
callback: function () {
|
|
||||||
save = true;
|
|
||||||
painterroInstance.save();
|
|
||||||
annotateImageOverlay.dismiss();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
painterroInstance = Painterro({
|
|
||||||
id: 'snap-annotation',
|
|
||||||
activeColor: '#ff0000',
|
|
||||||
activeColorAlpha: 1.0,
|
|
||||||
activeFillColor: '#fff',
|
|
||||||
activeFillColorAlpha: 0.0,
|
|
||||||
backgroundFillColor: '#000',
|
|
||||||
backgroundFillColorAlpha: 0.0,
|
|
||||||
defaultFontSize: 16,
|
|
||||||
defaultLineWidth: 2,
|
|
||||||
defaultTool: 'ellipse',
|
|
||||||
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
|
||||||
translation: {
|
|
||||||
name: 'en',
|
|
||||||
strings: {
|
|
||||||
lineColor: 'Line',
|
|
||||||
fillColor: 'Fill',
|
|
||||||
lineWidth: 'Size',
|
|
||||||
textColor: 'Color',
|
|
||||||
fontSize: 'Size',
|
|
||||||
fontStyle: 'Style'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveHandler: function (image, done) {
|
|
||||||
if (save) {
|
|
||||||
let url = image.asBlob(),
|
|
||||||
reader = new window.FileReader();
|
|
||||||
|
|
||||||
reader.readAsDataURL(url);
|
|
||||||
reader.onloadend = function () {
|
|
||||||
$scope.imageUrl = reader.result;
|
|
||||||
ngModel[field] = reader.result;
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
ngModel.field = imageUrl;
|
|
||||||
console.warn('You cancelled the annotation!!!');
|
|
||||||
}
|
|
||||||
|
|
||||||
done(true);
|
|
||||||
}
|
|
||||||
}).show(imageUrl);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return SnapshotPreviewController;
|
|
||||||
}
|
|
||||||
);
|
|
@ -9,10 +9,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<SearchResults v-if="search.length"
|
<SearchResults v-if="search.length"
|
||||||
ref="searchResults"
|
ref="searchResults"
|
||||||
:results="getSearchResults()"
|
:domain-object="internalDomainObject"
|
||||||
|
:results="searchedEntries"
|
||||||
@changeSectionPage="changeSelectedSection"
|
@changeSectionPage="changeSelectedSection"
|
||||||
|
@updateEntries="updateEntries"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div v-if="!search.length"
|
<div v-if="!search.length"
|
||||||
class="c-notebook__body"
|
class="c-notebook__body"
|
||||||
>
|
>
|
||||||
@ -105,10 +106,10 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NotebookEntry from './notebook-entry.vue';
|
import NotebookEntry from './NotebookEntry.vue';
|
||||||
import Search from '@/ui/components/search.vue';
|
import Search from '@/ui/components/search.vue';
|
||||||
import SearchResults from './search-results.vue';
|
import SearchResults from './SearchResults.vue';
|
||||||
import Sidebar from './sidebar.vue';
|
import Sidebar from './Sidebar.vue';
|
||||||
import { clearDefaultNotebook, getDefaultNotebook, setDefaultNotebook, setDefaultNotebookSection, setDefaultNotebookPage } from '../utils/notebook-storage';
|
import { clearDefaultNotebook, getDefaultNotebook, setDefaultNotebook, setDefaultNotebookSection, setDefaultNotebookPage } from '../utils/notebook-storage';
|
||||||
import { addNotebookEntry, createNewEmbed, getNotebookEntries } from '../utils/notebook-entries';
|
import { addNotebookEntry, createNewEmbed, getNotebookEntries } from '../utils/notebook-entries';
|
||||||
import { throttle } from 'lodash';
|
import { throttle } from 'lodash';
|
||||||
@ -153,6 +154,9 @@ export default {
|
|||||||
pages() {
|
pages() {
|
||||||
return this.getPages() || [];
|
return this.getPages() || [];
|
||||||
},
|
},
|
||||||
|
searchedEntries() {
|
||||||
|
return this.getSearchResults();
|
||||||
|
},
|
||||||
sections() {
|
sections() {
|
||||||
return this.internalDomainObject.configuration.sections || [];
|
return this.internalDomainObject.configuration.sections || [];
|
||||||
},
|
},
|
||||||
@ -172,8 +176,6 @@ export default {
|
|||||||
return this.sections.find(section => section.isSelected);
|
return this.sections.find(section => section.isSelected);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
},
|
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this.throttledSearchItem = throttle(this.searchItem, 500);
|
this.throttledSearchItem = throttle(this.searchItem, 500);
|
||||||
},
|
},
|
||||||
@ -259,7 +261,7 @@ export default {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
const snapshotId = event.dataTransfer.getData('snapshot/id');
|
const snapshotId = event.dataTransfer.getData('openmct/snapshot/id');
|
||||||
if (snapshotId.length) {
|
if (snapshotId.length) {
|
||||||
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
|
const snapshot = this.snapshotContainer.getSnapshot(snapshotId);
|
||||||
this.newEntry(snapshot);
|
this.newEntry(snapshot);
|
@ -17,7 +17,7 @@
|
|||||||
<div v-if="embed.snapshot"
|
<div v-if="embed.snapshot"
|
||||||
class="c-ne__embed__time"
|
class="c-ne__embed__time"
|
||||||
>
|
>
|
||||||
{{ formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss') }}
|
{{ createdOn }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -25,10 +25,10 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
import PopupMenu from './popup-menu.vue';
|
import PopupMenu from './PopupMenu.vue';
|
||||||
import PreviewAction from '../../../ui/preview/PreviewAction';
|
import PreviewAction from '../../../ui/preview/PreviewAction';
|
||||||
import Painterro from 'painterro';
|
|
||||||
import RemoveDialog from '../utils/removeDialog';
|
import RemoveDialog from '../utils/removeDialog';
|
||||||
|
import PainterroInstance from '../utils/painterroInstance';
|
||||||
import SnapshotTemplate from './snapshot-template.html';
|
import SnapshotTemplate from './snapshot-template.html';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
@ -56,7 +56,10 @@ export default {
|
|||||||
popupMenuItems: []
|
popupMenuItems: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
computed: {
|
||||||
|
createdOn() {
|
||||||
|
return this.formatTime(this.embed.createdOn, 'YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.addPopupMenuItems();
|
this.addPopupMenuItems();
|
||||||
@ -78,95 +81,44 @@ export default {
|
|||||||
this.popupMenuItems = [removeEmbed, preview];
|
this.popupMenuItems = [removeEmbed, preview];
|
||||||
},
|
},
|
||||||
annotateSnapshot() {
|
annotateSnapshot() {
|
||||||
const self = this;
|
|
||||||
|
|
||||||
let save = false;
|
|
||||||
let painterroInstance = {};
|
|
||||||
const annotateVue = new Vue({
|
const annotateVue = new Vue({
|
||||||
template: '<div id="snap-annotation"></div>'
|
template: '<div id="snap-annotation"></div>'
|
||||||
});
|
}).$mount();
|
||||||
|
|
||||||
let annotateOverlay = self.openmct.overlays.overlay({
|
const painterroInstance = new PainterroInstance(annotateVue.$el, this.updateSnapshot);
|
||||||
element: annotateVue.$mount().$el,
|
const annotateOverlay = this.openmct.overlays.overlay({
|
||||||
|
element: annotateVue.$el,
|
||||||
size: 'large',
|
size: 'large',
|
||||||
dismissable: false,
|
dismissable: false,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: 'Cancel',
|
label: 'Cancel',
|
||||||
callback: function () {
|
emphasis: true,
|
||||||
save = false;
|
callback: () => {
|
||||||
painterroInstance.save();
|
painterroInstance.dismiss();
|
||||||
annotateOverlay.dismiss();
|
annotateOverlay.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Save',
|
label: 'Save',
|
||||||
callback: function () {
|
callback: () => {
|
||||||
|
|
||||||
save = true;
|
|
||||||
painterroInstance.save();
|
painterroInstance.save();
|
||||||
annotateOverlay.dismiss();
|
annotateOverlay.dismiss();
|
||||||
|
this.snapshotOverlay.dismiss();
|
||||||
|
this.openSnapshot();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
onDestroy: function () {
|
onDestroy: () => {
|
||||||
annotateVue.$destroy(true);
|
annotateVue.$destroy(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
painterroInstance = Painterro({
|
painterroInstance.intialize();
|
||||||
id: 'snap-annotation',
|
painterroInstance.show(this.embed.snapshot.src);
|
||||||
activeColor: '#ff0000',
|
|
||||||
activeColorAlpha: 1.0,
|
|
||||||
activeFillColor: '#fff',
|
|
||||||
activeFillColorAlpha: 0.0,
|
|
||||||
backgroundFillColor: '#000',
|
|
||||||
backgroundFillColorAlpha: 0.0,
|
|
||||||
defaultFontSize: 16,
|
|
||||||
defaultLineWidth: 2,
|
|
||||||
defaultTool: 'ellipse',
|
|
||||||
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
|
||||||
translation: {
|
|
||||||
name: 'en',
|
|
||||||
strings: {
|
|
||||||
lineColor: 'Line',
|
|
||||||
fillColor: 'Fill',
|
|
||||||
lineWidth: 'Size',
|
|
||||||
textColor: 'Color',
|
|
||||||
fontSize: 'Size',
|
|
||||||
fontStyle: 'Style'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
saveHandler: function (image, done) {
|
|
||||||
if (save) {
|
|
||||||
const url = image.asBlob();
|
|
||||||
const reader = new window.FileReader();
|
|
||||||
reader.readAsDataURL(url);
|
|
||||||
reader.onloadend = function () {
|
|
||||||
const snapshot = reader.result;
|
|
||||||
const snapshotObject = {
|
|
||||||
src: snapshot,
|
|
||||||
type: url.type,
|
|
||||||
size: url.size,
|
|
||||||
modified: Date.now()
|
|
||||||
};
|
|
||||||
|
|
||||||
self.embed.snapshot = snapshotObject;
|
|
||||||
self.updateEmbed(self.embed);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
console.log('You cancelled the annotation!!!');
|
|
||||||
}
|
|
||||||
|
|
||||||
done(true);
|
|
||||||
}
|
|
||||||
}).show(this.embed.snapshot.src);
|
|
||||||
},
|
},
|
||||||
changeLocation() {
|
changeLocation() {
|
||||||
const link = this.embed.historicLink;
|
const link = this.embed.historicLink;
|
||||||
if (!link) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const bounds = this.openmct.time.bounds();
|
const bounds = this.openmct.time.bounds();
|
||||||
const isTimeBoundChanged = this.embed.bounds.start !== bounds.start
|
const isTimeBoundChanged = this.embed.bounds.start !== bounds.start
|
||||||
@ -209,7 +161,8 @@ export default {
|
|||||||
this.snapshot = new Vue({
|
this.snapshot = new Vue({
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
embed: self.embed
|
createdOn: this.createdOn,
|
||||||
|
embed: this.embed
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -218,13 +171,11 @@ export default {
|
|||||||
exportImage: self.exportImage
|
exportImage: self.exportImage
|
||||||
},
|
},
|
||||||
template: SnapshotTemplate
|
template: SnapshotTemplate
|
||||||
});
|
}).$mount();
|
||||||
|
|
||||||
const snapshotOverlay = this.openmct.overlays.overlay({
|
this.snapshotOverlay = this.openmct.overlays.overlay({
|
||||||
element: this.snapshot.$mount().$el,
|
element: this.snapshot.$el,
|
||||||
onDestroy: () => {
|
onDestroy: () => this.snapshot.$destroy(true),
|
||||||
this.snapshot.$destroy(true);
|
|
||||||
},
|
|
||||||
size: 'large',
|
size: 'large',
|
||||||
dismissable: true,
|
dismissable: true,
|
||||||
buttons: [
|
buttons: [
|
||||||
@ -232,7 +183,7 @@ export default {
|
|||||||
label: 'Done',
|
label: 'Done',
|
||||||
emphasis: true,
|
emphasis: true,
|
||||||
callback: () => {
|
callback: () => {
|
||||||
snapshotOverlay.dismiss();
|
this.snapshotOverlay.dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -262,6 +213,10 @@ export default {
|
|||||||
},
|
},
|
||||||
updateEmbed(embed) {
|
updateEmbed(embed) {
|
||||||
this.$emit('updateEmbed', embed);
|
this.$emit('updateEmbed', embed);
|
||||||
|
},
|
||||||
|
updateSnapshot(snapshotObject) {
|
||||||
|
this.embed.snapshot = snapshotObject;
|
||||||
|
this.updateEmbed(this.embed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -1,13 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-notebook__entry c-ne has-local-controls"
|
<div class="c-notebook__entry c-ne has-local-controls"
|
||||||
@dragover="dragover"
|
@dragover="changeCursor"
|
||||||
@drop.capture="dropCapture"
|
@drop.capture="cancelEditMode"
|
||||||
@drop.prevent="dropOnEntry(entry.id, $event)"
|
@drop.prevent="dropOnEntry"
|
||||||
>
|
>
|
||||||
<div class="c-ne__time-and-content">
|
<div class="c-ne__time-and-content">
|
||||||
<div class="c-ne__time">
|
<div class="c-ne__time">
|
||||||
<span>{{ formatTime(entry.createdOn, 'YYYY-MM-DD') }}</span>
|
<span>{{ createdOnDate }}</span>
|
||||||
<span>{{ formatTime(entry.createdOn, 'HH:mm:ss') }}</span>
|
<span>{{ createdOnTime }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-ne__content">
|
<div class="c-ne__content">
|
||||||
<div :id="entry.id"
|
<div :id="entry.id"
|
||||||
@ -15,8 +15,8 @@
|
|||||||
:class="{'c-input-inline' : !readOnly }"
|
:class="{'c-input-inline' : !readOnly }"
|
||||||
:contenteditable="!readOnly"
|
:contenteditable="!readOnly"
|
||||||
:style="!entry.text.length ? defaultEntryStyle : ''"
|
:style="!entry.text.length ? defaultEntryStyle : ''"
|
||||||
@blur="textBlur($event, entry.id)"
|
@blur="updateEntryValue($event, entry.id)"
|
||||||
@focus="textFocus($event, entry.id)"
|
@focus="updateCurrentEntryValue($event, entry.id)"
|
||||||
>{{ entry.text.length ? entry.text : defaultText }}</div>
|
>{{ entry.text.length ? entry.text : defaultText }}</div>
|
||||||
<div class="c-snapshots c-ne__embeds">
|
<div class="c-snapshots c-ne__embeds">
|
||||||
<NotebookEmbed v-for="embed in entry.embeds"
|
<NotebookEmbed v-for="embed in entry.embeds"
|
||||||
@ -57,7 +57,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NotebookEmbed from './notebook-embed.vue';
|
import NotebookEmbed from './NotebookEmbed.vue';
|
||||||
import { createNewEmbed, getEntryPosById, getNotebookEntries } from '../utils/notebook-entries';
|
import { createNewEmbed, getEntryPosById, getNotebookEntries } from '../utils/notebook-entries';
|
||||||
import Moment from 'moment';
|
import Moment from 'moment';
|
||||||
|
|
||||||
@ -114,29 +114,32 @@ export default {
|
|||||||
defaultText: 'add description'
|
defaultText: 'add description'
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
computed: {
|
||||||
entry() {
|
createdOnDate() {
|
||||||
|
return this.formatTime(this.entry.createdOn, 'YYYY-MM-DD');
|
||||||
},
|
},
|
||||||
readOnly(readOnly) {
|
createdOnTime() {
|
||||||
},
|
return this.formatTime(this.entry.createdOn, 'HH:mm:ss');
|
||||||
selectedSection(selectedSection) {
|
|
||||||
},
|
|
||||||
selectedPage(selectedSection) {
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.updateEntries = this.updateEntries.bind(this);
|
this.updateEntries = this.updateEntries.bind(this);
|
||||||
},
|
this.dropOnEntry = this.dropOnEntry.bind(this);
|
||||||
beforeDestory() {
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
cancelEditMode(event) {
|
||||||
|
const isEditing = this.openmct.editor.isEditing();
|
||||||
|
if (isEditing) {
|
||||||
|
this.openmct.editor.cancel();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
changeCursor() {
|
||||||
|
event.preventDefault();
|
||||||
|
event.dataTransfer.dropEffect = "copy";
|
||||||
|
},
|
||||||
deleteEntry() {
|
deleteEntry() {
|
||||||
const self = this;
|
const self = this;
|
||||||
if (!self.domainObject || !self.selectedSection || !self.selectedPage || !self.entry.id) {
|
const entryPosById = self.entryPosById(self.entry.id);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entryPosById = this.entryPosById(this.entry.id);
|
|
||||||
if (entryPosById === -1) {
|
if (entryPosById === -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -151,7 +154,7 @@ export default {
|
|||||||
callback: () => {
|
callback: () => {
|
||||||
const entries = getNotebookEntries(self.domainObject, self.selectedSection, self.selectedPage);
|
const entries = getNotebookEntries(self.domainObject, self.selectedSection, self.selectedPage);
|
||||||
entries.splice(entryPosById, 1);
|
entries.splice(entryPosById, 1);
|
||||||
this.updateEntries(entries);
|
self.updateEntries(entries);
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -164,24 +167,10 @@ export default {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
dragover() {
|
dropOnEntry($event) {
|
||||||
event.preventDefault();
|
|
||||||
event.dataTransfer.dropEffect = "copy";
|
|
||||||
},
|
|
||||||
dropCapture(event) {
|
|
||||||
const isEditing = this.openmct.editor.isEditing();
|
|
||||||
if (isEditing) {
|
|
||||||
this.openmct.editor.cancel();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dropOnEntry(entryId, $event) {
|
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
|
|
||||||
if (!this.domainObject || !this.selectedSection || !this.selectedPage) {
|
const snapshotId = $event.dataTransfer.getData('openmct/snapshot/id');
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const snapshotId = $event.dataTransfer.getData('snapshot/id');
|
|
||||||
if (snapshotId.length) {
|
if (snapshotId.length) {
|
||||||
this.moveSnapshot(snapshotId);
|
this.moveSnapshot(snapshotId);
|
||||||
|
|
||||||
@ -190,7 +179,7 @@ export default {
|
|||||||
|
|
||||||
const data = $event.dataTransfer.getData('openmct/domain-object-path');
|
const data = $event.dataTransfer.getData('openmct/domain-object-path');
|
||||||
const objectPath = JSON.parse(data);
|
const objectPath = JSON.parse(data);
|
||||||
const entryPos = this.entryPosById(entryId);
|
const entryPos = this.entryPosById(this.entry.id);
|
||||||
const bounds = this.openmct.time.bounds();
|
const bounds = this.openmct.time.bounds();
|
||||||
const snapshotMeta = {
|
const snapshotMeta = {
|
||||||
bounds,
|
bounds,
|
||||||
@ -253,7 +242,44 @@ export default {
|
|||||||
selection.removeAllRanges();
|
selection.removeAllRanges();
|
||||||
selection.addRange(range);
|
selection.addRange(range);
|
||||||
},
|
},
|
||||||
textBlur($event, entryId) {
|
updateCurrentEntryValue($event) {
|
||||||
|
if (this.readOnly) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = $event.target;
|
||||||
|
this.currentEntryValue = target ? target.innerText : '';
|
||||||
|
|
||||||
|
if (!this.entry.text.length) {
|
||||||
|
this.selectTextInsideElement(target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateEmbed(newEmbed) {
|
||||||
|
this.entry.embeds.some(e => {
|
||||||
|
const found = (e.id === newEmbed.id);
|
||||||
|
if (found) {
|
||||||
|
e = newEmbed;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateEntry(this.entry);
|
||||||
|
},
|
||||||
|
updateEntry(newEntry) {
|
||||||
|
const entries = getNotebookEntries(this.domainObject, this.selectedSection, this.selectedPage);
|
||||||
|
entries.some(entry => {
|
||||||
|
const found = (entry.id === newEntry.id);
|
||||||
|
if (found) {
|
||||||
|
entry = newEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.updateEntries(entries);
|
||||||
|
},
|
||||||
|
updateEntryValue($event, entryId) {
|
||||||
if (!this.domainObject || !this.selectedSection || !this.selectedPage) {
|
if (!this.domainObject || !this.selectedSection || !this.selectedPage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -272,42 +298,6 @@ export default {
|
|||||||
this.updateEntries(entries);
|
this.updateEntries(entries);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
textFocus($event) {
|
|
||||||
if (this.readOnly || !this.domainObject || !this.selectedSection || !this.selectedPage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const target = $event.target;
|
|
||||||
this.currentEntryValue = target ? target.innerText : '';
|
|
||||||
|
|
||||||
if (!this.entry.text.length) {
|
|
||||||
this.selectTextInsideElement(target);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateEmbed(newEmbed) {
|
|
||||||
let embed = this.entry.embeds.find(e => e.id === newEmbed.id);
|
|
||||||
|
|
||||||
if (!embed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
embed = newEmbed;
|
|
||||||
this.updateEntry(this.entry);
|
|
||||||
},
|
|
||||||
updateEntry(newEntry) {
|
|
||||||
if (!this.domainObject || !this.selectedSection || !this.selectedPage) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const entries = getNotebookEntries(this.domainObject, this.selectedSection, this.selectedPage);
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.id === newEntry.id) {
|
|
||||||
entry = newEntry;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.updateEntries(entries);
|
|
||||||
},
|
|
||||||
updateEntries(entries) {
|
updateEntries(entries) {
|
||||||
this.$emit('updateEntries', entries);
|
this.$emit('updateEntries', entries);
|
||||||
}
|
}
|
@ -49,8 +49,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NotebookEmbed from './notebook-embed.vue';
|
import NotebookEmbed from './NotebookEmbed.vue';
|
||||||
import PopupMenu from './popup-menu.vue';
|
import PopupMenu from './PopupMenu.vue';
|
||||||
import RemoveDialog from '../utils/removeDialog';
|
import RemoveDialog from '../utils/removeDialog';
|
||||||
import { NOTEBOOK_SNAPSHOT_MAX_COUNT } from '../snapshot-container';
|
import { NOTEBOOK_SNAPSHOT_MAX_COUNT } from '../snapshot-container';
|
||||||
import { EVENT_SNAPSHOTS_UPDATED } from '../notebook-constants';
|
import { EVENT_SNAPSHOTS_UPDATED } from '../notebook-constants';
|
||||||
@ -81,8 +81,6 @@ export default {
|
|||||||
this.snapshotContainer.on(EVENT_SNAPSHOTS_UPDATED, this.snapshotsUpdated);
|
this.snapshotContainer.on(EVENT_SNAPSHOTS_UPDATED, this.snapshotsUpdated);
|
||||||
this.snapshots = this.snapshotContainer.getSnapshots();
|
this.snapshots = this.snapshotContainer.getSnapshots();
|
||||||
},
|
},
|
||||||
beforeDestory() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
addPopupMenuItems() {
|
addPopupMenuItems() {
|
||||||
const removeSnapshot = {
|
const removeSnapshot = {
|
||||||
@ -122,7 +120,7 @@ export default {
|
|||||||
},
|
},
|
||||||
startEmbedDrag(snapshot, event) {
|
startEmbedDrag(snapshot, event) {
|
||||||
event.dataTransfer.setData('text/plain', snapshot.id);
|
event.dataTransfer.setData('text/plain', snapshot.id);
|
||||||
event.dataTransfer.setData('snapshot/id', snapshot.id);
|
event.dataTransfer.setData('openmct/snapshot/id', snapshot.id);
|
||||||
},
|
},
|
||||||
updateSnapshot(snapshot) {
|
updateSnapshot(snapshot) {
|
||||||
this.snapshotContainer.updateSnapshot(snapshot);
|
this.snapshotContainer.updateSnapshot(snapshot);
|
@ -18,7 +18,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SnapshotContainerComponent from './notebook-snapshot-container.vue';
|
import SnapshotContainerComponent from './NotebookSnapshotContainer.vue';
|
||||||
import { EVENT_SNAPSHOTS_UPDATED } from '../notebook-constants';
|
import { EVENT_SNAPSHOTS_UPDATED } from '../notebook-constants';
|
||||||
import { NOTEBOOK_SNAPSHOT_MAX_COUNT } from '../snapshot-container';
|
import { NOTEBOOK_SNAPSHOT_MAX_COUNT } from '../snapshot-container';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
@ -19,7 +19,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { deleteNotebookEntries } from '../utils/notebook-entries';
|
import { deleteNotebookEntries } from '../utils/notebook-entries';
|
||||||
import { getDefaultNotebook } from '../utils/notebook-storage';
|
import { getDefaultNotebook } from '../utils/notebook-storage';
|
||||||
import Page from './page-component.vue';
|
import Page from './PageComponent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
@ -70,12 +70,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
deletePage(id) {
|
deletePage(id) {
|
||||||
const selectedSection = this.sections.find(s => s.isSelected);
|
const selectedSection = this.sections.find(s => s.isSelected);
|
@ -14,7 +14,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PopupMenu from './popup-menu.vue';
|
import PopupMenu from './PopupMenu.vue';
|
||||||
import RemoveDialog from '../utils/removeDialog';
|
import RemoveDialog from '../utils/removeDialog';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -55,8 +55,6 @@ export default {
|
|||||||
this.addPopupMenuItems();
|
this.addPopupMenuItems();
|
||||||
this.toggleContentEditable();
|
this.toggleContentEditable();
|
||||||
},
|
},
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
addPopupMenuItems() {
|
addPopupMenuItems() {
|
||||||
const removePage = {
|
const removePage = {
|
@ -8,7 +8,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import MenuItems from './menu-items.vue';
|
import MenuItems from './MenuItems.vue';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
@ -4,26 +4,34 @@
|
|||||||
<div class="c-notebook__entries">
|
<div class="c-notebook__entries">
|
||||||
<NotebookEntry v-for="(result, index) in results"
|
<NotebookEntry v-for="(result, index) in results"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
:domain-object="domainObject"
|
||||||
:result="result"
|
:result="result"
|
||||||
:entry="result.entry"
|
:entry="result.entry"
|
||||||
:read-only="true"
|
:read-only="true"
|
||||||
:selected-page="null"
|
:selected-page="result.page"
|
||||||
:selected-section="null"
|
:selected-section="result.section"
|
||||||
@changeSectionPage="changeSectionPage"
|
@changeSectionPage="changeSectionPage"
|
||||||
|
@updateEntries="updateEntries"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import NotebookEntry from './notebook-entry.vue';
|
import NotebookEntry from './NotebookEntry.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'domainObject'],
|
inject: ['openmct', 'snapshotContainer'],
|
||||||
components: {
|
components: {
|
||||||
NotebookEntry
|
NotebookEntry
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
domainObject: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
},
|
||||||
results: {
|
results: {
|
||||||
type: Array,
|
type: Array,
|
||||||
default() {
|
default() {
|
||||||
@ -31,19 +39,12 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data() {
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
results(newResults) {}
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
changeSectionPage(data) {
|
changeSectionPage(data) {
|
||||||
this.$emit('changeSectionPage', data);
|
this.$emit('changeSectionPage', data);
|
||||||
|
},
|
||||||
|
updateEntries(entries) {
|
||||||
|
this.$emit('updateEntries', entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
@ -19,7 +19,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import { deleteNotebookEntries } from '../utils/notebook-entries';
|
import { deleteNotebookEntries } from '../utils/notebook-entries';
|
||||||
import { getDefaultNotebook } from '../utils/notebook-storage';
|
import { getDefaultNotebook } from '../utils/notebook-storage';
|
||||||
import sectionComponent from './section-component.vue';
|
import sectionComponent from './SectionComponent.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
@ -57,12 +57,6 @@ export default {
|
|||||||
return {
|
return {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
deleteSection(id) {
|
deleteSection(id) {
|
||||||
const section = this.sections.find(s => s.id === id);
|
const section = this.sections.find(s => s.id === id);
|
@ -17,7 +17,7 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import PopupMenu from './popup-menu.vue';
|
import PopupMenu from './PopupMenu.vue';
|
||||||
import RemoveDialog from '../utils/removeDialog';
|
import RemoveDialog from '../utils/removeDialog';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -58,8 +58,6 @@ export default {
|
|||||||
this.addPopupMenuItems();
|
this.addPopupMenuItems();
|
||||||
this.toggleContentEditable();
|
this.toggleContentEditable();
|
||||||
},
|
},
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
addPopupMenuItems() {
|
addPopupMenuItems() {
|
||||||
const removeSection = {
|
const removeSection = {
|
@ -56,8 +56,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SectionCollection from './section-collection.vue';
|
import SectionCollection from './SectionCollection.vue';
|
||||||
import PageCollection from './page-collection.vue';
|
import PageCollection from './PageCollection.vue';
|
||||||
import uuid from 'uuid';
|
import uuid from 'uuid';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -139,8 +139,6 @@ export default {
|
|||||||
this.addSection();
|
this.addSection();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
methods: {
|
||||||
addPage() {
|
addPage() {
|
||||||
const pageTitle = this.pageTitle;
|
const pageTitle = this.pageTitle;
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<div class="l-browse-bar__end">
|
<div class="l-browse-bar__end">
|
||||||
<div class="l-browse-bar__snapshot-datetime">
|
<div class="l-browse-bar__snapshot-datetime">
|
||||||
SNAPSHOT {{formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss')}}
|
SNAPSHOT {{ createdOn }}
|
||||||
</div>
|
</div>
|
||||||
<span class="c-button-set c-button-set--strip-h">
|
<span class="c-button-set c-button-set--strip-h">
|
||||||
<button
|
<button
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Notebook from './components/notebook.vue';
|
import Notebook from './components/Notebook.vue';
|
||||||
import NotebookSnapshotIndicator from './components/notebook-snapshot-indicator.vue';
|
import NotebookSnapshotIndicator from './components/NotebookSnapshotIndicator.vue';
|
||||||
import SnapshotContainer from './snapshot-container';
|
import SnapshotContainer from './snapshot-container';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
@ -95,7 +95,8 @@ export default function NotebookPlugin() {
|
|||||||
template: '<NotebookSnapshotIndicator></NotebookSnapshotIndicator>'
|
template: '<NotebookSnapshotIndicator></NotebookSnapshotIndicator>'
|
||||||
});
|
});
|
||||||
const indicator = {
|
const indicator = {
|
||||||
element: notebookSnapshotIndicator.$mount().$el
|
element: notebookSnapshotIndicator.$mount().$el,
|
||||||
|
key: 'notebook-snapshot-indicator'
|
||||||
};
|
};
|
||||||
|
|
||||||
openmct.indicators.add(indicator);
|
openmct.indicators.add(indicator);
|
||||||
|
222
src/plugins/notebook/pluginSpec.js
Normal file
222
src/plugins/notebook/pluginSpec.js
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import { createOpenMct, createMouseEvent, resetApplicationState } from 'utils/testing';
|
||||||
|
import NotebookPlugin from './plugin';
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
let openmct;
|
||||||
|
let notebookDefinition;
|
||||||
|
let notebookPlugin;
|
||||||
|
let element;
|
||||||
|
let child;
|
||||||
|
let appHolder;
|
||||||
|
|
||||||
|
const notebookDomainObject = {
|
||||||
|
identifier: {
|
||||||
|
key: 'notebook',
|
||||||
|
namespace: ''
|
||||||
|
},
|
||||||
|
type: 'notebook'
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("Notebook plugin:", () => {
|
||||||
|
beforeAll(done => {
|
||||||
|
appHolder = document.createElement('div');
|
||||||
|
appHolder.style.width = '640px';
|
||||||
|
appHolder.style.height = '480px';
|
||||||
|
|
||||||
|
openmct = createOpenMct();
|
||||||
|
|
||||||
|
element = document.createElement('div');
|
||||||
|
child = document.createElement('div');
|
||||||
|
element.appendChild(child);
|
||||||
|
|
||||||
|
notebookPlugin = new NotebookPlugin();
|
||||||
|
openmct.install(notebookPlugin);
|
||||||
|
|
||||||
|
notebookDefinition = openmct.types.get('notebook').definition;
|
||||||
|
notebookDefinition.initialize(notebookDomainObject);
|
||||||
|
|
||||||
|
openmct.on('start', done);
|
||||||
|
openmct.start(appHolder);
|
||||||
|
|
||||||
|
document.body.append(appHolder);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
appHolder.remove();
|
||||||
|
resetApplicationState(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has type as Notebook", () => {
|
||||||
|
expect(notebookDefinition.name).toEqual('Notebook');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is creatable", () => {
|
||||||
|
expect(notebookDefinition.creatable).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Notebook view:", () => {
|
||||||
|
let notebookViewProvider;
|
||||||
|
let notebookView;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
const notebookViewObject = {
|
||||||
|
...notebookDomainObject,
|
||||||
|
id: "test-object",
|
||||||
|
name: 'Notebook',
|
||||||
|
configuration: {
|
||||||
|
defaultSort: 'oldest',
|
||||||
|
entries: {},
|
||||||
|
pageTitle: 'Page',
|
||||||
|
sections: [],
|
||||||
|
sectionTitle: 'Section',
|
||||||
|
type: 'General'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const notebookObject = {
|
||||||
|
name: 'Notebook View',
|
||||||
|
key: 'notebook-vue',
|
||||||
|
creatable: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const applicableViews = openmct.objectViews.get(notebookViewObject);
|
||||||
|
notebookViewProvider = applicableViews.find(viewProvider => viewProvider.key === notebookObject.key);
|
||||||
|
notebookView = notebookViewProvider.view(notebookViewObject);
|
||||||
|
|
||||||
|
notebookView.show(child);
|
||||||
|
|
||||||
|
return Vue.nextTick();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
notebookView.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("provides notebook view", () => {
|
||||||
|
expect(notebookViewProvider).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders notebook element", () => {
|
||||||
|
const notebookElement = element.querySelectorAll('.c-notebook');
|
||||||
|
expect(notebookElement.length).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders major elements", () => {
|
||||||
|
const notebookElement = element.querySelector('.c-notebook');
|
||||||
|
const searchElement = notebookElement.querySelector('.c-search');
|
||||||
|
const sidebarElement = notebookElement.querySelector('.c-sidebar');
|
||||||
|
const pageViewElement = notebookElement.querySelector('.c-notebook__page-view');
|
||||||
|
const hasMajorElements = Boolean(searchElement && sidebarElement && pageViewElement);
|
||||||
|
|
||||||
|
expect(hasMajorElements).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Notebook Snapshots view:", () => {
|
||||||
|
let snapshotIndicator;
|
||||||
|
let drawerElement;
|
||||||
|
|
||||||
|
function clickSnapshotIndicator() {
|
||||||
|
const indicator = element.querySelector('.icon-notebook');
|
||||||
|
const button = indicator.querySelector('button');
|
||||||
|
const clickEvent = createMouseEvent('click');
|
||||||
|
|
||||||
|
button.dispatchEvent(clickEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
snapshotIndicator = openmct.indicators.indicatorObjects
|
||||||
|
.find(indicator => indicator.key === 'notebook-snapshot-indicator').element;
|
||||||
|
|
||||||
|
element.append(snapshotIndicator);
|
||||||
|
|
||||||
|
return Vue.nextTick();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
snapshotIndicator.remove();
|
||||||
|
if (drawerElement) {
|
||||||
|
drawerElement.remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
drawerElement = document.querySelector('.l-shell__drawer');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
if (drawerElement) {
|
||||||
|
drawerElement.classList.remove('is-expanded');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it("has Snapshots indicator", () => {
|
||||||
|
const hasSnapshotIndicator = snapshotIndicator !== null && snapshotIndicator !== undefined;
|
||||||
|
expect(hasSnapshotIndicator).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("snapshots container has class isExpanded", () => {
|
||||||
|
let classes = drawerElement.classList;
|
||||||
|
const isExpandedBefore = classes.contains('is-expanded');
|
||||||
|
|
||||||
|
clickSnapshotIndicator();
|
||||||
|
classes = drawerElement.classList;
|
||||||
|
const isExpandedAfterFirstClick = classes.contains('is-expanded');
|
||||||
|
|
||||||
|
const success = isExpandedBefore === false
|
||||||
|
&& isExpandedAfterFirstClick === true;
|
||||||
|
|
||||||
|
expect(success).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("snapshots container does not have class isExpanded", () => {
|
||||||
|
let classes = drawerElement.classList;
|
||||||
|
const isExpandedBefore = classes.contains('is-expanded');
|
||||||
|
|
||||||
|
clickSnapshotIndicator();
|
||||||
|
classes = drawerElement.classList;
|
||||||
|
const isExpandedAfterFirstClick = classes.contains('is-expanded');
|
||||||
|
|
||||||
|
clickSnapshotIndicator();
|
||||||
|
classes = drawerElement.classList;
|
||||||
|
const isExpandedAfterSecondClick = classes.contains('is-expanded');
|
||||||
|
|
||||||
|
const success = isExpandedBefore === false
|
||||||
|
&& isExpandedAfterFirstClick === true
|
||||||
|
&& isExpandedAfterSecondClick === false;
|
||||||
|
|
||||||
|
expect(success).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("show notebook snapshots container text", () => {
|
||||||
|
clickSnapshotIndicator();
|
||||||
|
|
||||||
|
const notebookSnapshots = drawerElement.querySelector('.l-browse-bar__object-name');
|
||||||
|
const snapshotsText = notebookSnapshots.textContent.trim();
|
||||||
|
|
||||||
|
expect(snapshotsText).toBe('Notebook Snapshots');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
195
src/plugins/notebook/utils/notebook-entriesSpec.js
Normal file
195
src/plugins/notebook/utils/notebook-entriesSpec.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
import * as NotebookEntries from './notebook-entries';
|
||||||
|
import { createOpenMct, spyOnBuiltins, resetApplicationState } from 'utils/testing';
|
||||||
|
|
||||||
|
const notebookStorage = {
|
||||||
|
domainObject: {
|
||||||
|
name: 'notebook',
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: 'test-notebook'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notebookMeta: {
|
||||||
|
name: 'notebook',
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: 'test-notebook'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
id: '03a79b6a-971c-4e56-9892-ec536332c3f0',
|
||||||
|
isDefault: true,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'section',
|
||||||
|
pages: [],
|
||||||
|
sectionTitle: 'Section'
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00',
|
||||||
|
isDefault: true,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'page',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const notebookEntries = {
|
||||||
|
'03a79b6a-971c-4e56-9892-ec536332c3f0': {
|
||||||
|
'8b548fd9-2b8a-4b02-93a9-4138e22eba00': []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const notebookDomainObject = {
|
||||||
|
identifier: {
|
||||||
|
key: 'notebook',
|
||||||
|
namespace: ''
|
||||||
|
},
|
||||||
|
type: 'notebook',
|
||||||
|
configuration: {
|
||||||
|
defaultSort: 'oldest',
|
||||||
|
entries: notebookEntries,
|
||||||
|
pageTitle: 'Page',
|
||||||
|
sections: [],
|
||||||
|
sectionTitle: 'Section',
|
||||||
|
type: 'General'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedSection = {
|
||||||
|
id: '03a79b6a-971c-4e56-9892-ec536332c3f0',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'Day 1',
|
||||||
|
pages: [
|
||||||
|
{
|
||||||
|
id: '54deb3d5-8267-4be4-95e9-3579ed8c082d',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: false,
|
||||||
|
name: 'Shift 1',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '2ea41c78-8e60-4657-a350-53f1a1fa3021',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: false,
|
||||||
|
name: 'Shift 2',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'Unnamed Page',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
sectionTitle: 'Section'
|
||||||
|
};
|
||||||
|
|
||||||
|
const selectedPage = {
|
||||||
|
id: '8b548fd9-2b8a-4b02-93a9-4138e22eba00',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'Unnamed Page',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
};
|
||||||
|
|
||||||
|
let openmct;
|
||||||
|
|
||||||
|
describe('Notebook Entries:', () => {
|
||||||
|
beforeEach(done => {
|
||||||
|
openmct = createOpenMct();
|
||||||
|
window.localStorage.setItem('notebook-storage', null);
|
||||||
|
spyOnBuiltins(['mutate'], openmct.objects);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
notebookDomainObject.configuration.entries[selectedSection.id][selectedPage.id] = [];
|
||||||
|
resetApplicationState(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getNotebookEntries has no entries', () => {
|
||||||
|
const entries = NotebookEntries.getNotebookEntries(notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
expect(entries.length).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('addNotebookEntry mutates object', () => {
|
||||||
|
NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
|
||||||
|
expect(openmct.objects.mutate).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('addNotebookEntry adds entry', () => {
|
||||||
|
NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
const entries = NotebookEntries.getNotebookEntries(notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
expect(entries.length).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getEntryPosById returns valid position', () => {
|
||||||
|
const entryId = NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
const position = NotebookEntries.getEntryPosById(entryId, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
expect(position).toEqual(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getEntryPosById returns valid position', () => {
|
||||||
|
const entryId1 = NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
const position1 = NotebookEntries.getEntryPosById(entryId1, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
const entryId2 = NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
const position2 = NotebookEntries.getEntryPosById(entryId2, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
const entryId3 = NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
const position3 = NotebookEntries.getEntryPosById(entryId3, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
const success = position1 === 0
|
||||||
|
&& position2 === 1
|
||||||
|
&& position3 === 2;
|
||||||
|
|
||||||
|
expect(success).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deleteNotebookEntries mutates object', () => {
|
||||||
|
openmct.objects.mutate.calls.reset();
|
||||||
|
|
||||||
|
NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
NotebookEntries.deleteNotebookEntries(openmct, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
expect(openmct.objects.mutate).toHaveBeenCalledTimes(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('deleteNotebookEntries deletes correct entry', () => {
|
||||||
|
NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
NotebookEntries.addNotebookEntry(openmct, notebookDomainObject, notebookStorage);
|
||||||
|
|
||||||
|
NotebookEntries.deleteNotebookEntries(openmct, notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
const afterEntries = NotebookEntries.getNotebookEntries(notebookDomainObject, selectedSection, selectedPage);
|
||||||
|
|
||||||
|
expect(afterEntries).toEqual(null);
|
||||||
|
});
|
||||||
|
});
|
125
src/plugins/notebook/utils/notebook-storageSpec.js
Normal file
125
src/plugins/notebook/utils/notebook-storageSpec.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2020, 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import * as NotebookStorage from './notebook-storage';
|
||||||
|
import { createOpenMct, resetApplicationState } from 'utils/testing';
|
||||||
|
|
||||||
|
const notebookStorage = {
|
||||||
|
domainObject: {
|
||||||
|
name: 'notebook',
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: 'test-notebook'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notebookMeta: {
|
||||||
|
name: 'notebook',
|
||||||
|
identifier: {
|
||||||
|
namespace: '',
|
||||||
|
key: 'test-notebook'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
section: {
|
||||||
|
id: 'temp-section',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'section',
|
||||||
|
pages: [],
|
||||||
|
sectionTitle: 'Section'
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
id: 'temp-page',
|
||||||
|
isDefault: false,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'page',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let openmct = createOpenMct();
|
||||||
|
|
||||||
|
describe('Notebook Storage:', () => {
|
||||||
|
beforeEach((done) => {
|
||||||
|
openmct = createOpenMct();
|
||||||
|
window.localStorage.setItem('notebook-storage', null);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
resetApplicationState(openmct);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has empty local Storage', () => {
|
||||||
|
expect(window.localStorage).not.toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has null notebookstorage on clearDefaultNotebook', () => {
|
||||||
|
window.localStorage.setItem('notebook-storage', notebookStorage);
|
||||||
|
NotebookStorage.clearDefaultNotebook();
|
||||||
|
const defaultNotebook = NotebookStorage.getDefaultNotebook();
|
||||||
|
|
||||||
|
expect(defaultNotebook).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has correct notebookstorage on setDefaultNotebook', () => {
|
||||||
|
NotebookStorage.setDefaultNotebook(openmct, notebookStorage);
|
||||||
|
const defaultNotebook = NotebookStorage.getDefaultNotebook();
|
||||||
|
|
||||||
|
expect(JSON.stringify(defaultNotebook)).toBe(JSON.stringify(notebookStorage));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has correct section on setDefaultNotebookSection', () => {
|
||||||
|
const section = {
|
||||||
|
id: 'new-temp-section',
|
||||||
|
isDefault: true,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'new section',
|
||||||
|
pages: [],
|
||||||
|
sectionTitle: 'Section'
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookStorage.setDefaultNotebook(openmct, notebookStorage);
|
||||||
|
NotebookStorage.setDefaultNotebookSection(section);
|
||||||
|
|
||||||
|
const defaultNotebook = NotebookStorage.getDefaultNotebook();
|
||||||
|
const newSection = defaultNotebook.section;
|
||||||
|
expect(JSON.stringify(section)).toBe(JSON.stringify(newSection));
|
||||||
|
});
|
||||||
|
|
||||||
|
it('has correct page on setDefaultNotebookPage', () => {
|
||||||
|
const page = {
|
||||||
|
id: 'new-temp-page',
|
||||||
|
isDefault: true,
|
||||||
|
isSelected: true,
|
||||||
|
name: 'new page',
|
||||||
|
pageTitle: 'Page'
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookStorage.setDefaultNotebook(openmct, notebookStorage);
|
||||||
|
NotebookStorage.setDefaultNotebookPage(page);
|
||||||
|
|
||||||
|
const defaultNotebook = NotebookStorage.getDefaultNotebook();
|
||||||
|
const newPage = defaultNotebook.page;
|
||||||
|
expect(JSON.stringify(page)).toBe(JSON.stringify(newPage));
|
||||||
|
});
|
||||||
|
});
|
79
src/plugins/notebook/utils/painterroInstance.js
Normal file
79
src/plugins/notebook/utils/painterroInstance.js
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
import Painterro from 'painterro';
|
||||||
|
|
||||||
|
const DEFAULT_CONFIG = {
|
||||||
|
activeColor: '#ff0000',
|
||||||
|
activeColorAlpha: 1.0,
|
||||||
|
activeFillColor: '#fff',
|
||||||
|
activeFillColorAlpha: 0.0,
|
||||||
|
backgroundFillColor: '#000',
|
||||||
|
backgroundFillColorAlpha: 0.0,
|
||||||
|
defaultFontSize: 16,
|
||||||
|
defaultLineWidth: 2,
|
||||||
|
defaultTool: 'ellipse',
|
||||||
|
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
||||||
|
translation: {
|
||||||
|
name: 'en',
|
||||||
|
strings: {
|
||||||
|
lineColor: 'Line',
|
||||||
|
fillColor: 'Fill',
|
||||||
|
lineWidth: 'Size',
|
||||||
|
textColor: 'Color',
|
||||||
|
fontSize: 'Size',
|
||||||
|
fontStyle: 'Style'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default class PainterroInstance {
|
||||||
|
constructor(element, saveCallback) {
|
||||||
|
this.elementId = element.id;
|
||||||
|
this.isSave = false;
|
||||||
|
this.painterroInstance = null;
|
||||||
|
this.saveCallback = saveCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
dismiss() {
|
||||||
|
this.isSave = false;
|
||||||
|
this.painterroInstance.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
intialize() {
|
||||||
|
this.config = Object.assign({}, DEFAULT_CONFIG);
|
||||||
|
|
||||||
|
this.config.id = this.elementId;
|
||||||
|
this.config.saveHandler = this.saveHandler.bind(this);
|
||||||
|
|
||||||
|
this.painterro = Painterro(this.config);
|
||||||
|
}
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.isSave = true;
|
||||||
|
this.painterroInstance.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
saveHandler(image, done) {
|
||||||
|
if (this.isSave) {
|
||||||
|
const self = this;
|
||||||
|
const url = image.asBlob();
|
||||||
|
const reader = new window.FileReader();
|
||||||
|
reader.readAsDataURL(url);
|
||||||
|
reader.onloadend = () => {
|
||||||
|
const snapshot = reader.result;
|
||||||
|
const snapshotObject = {
|
||||||
|
src: snapshot,
|
||||||
|
type: url.type,
|
||||||
|
size: url.size,
|
||||||
|
modified: Date.now()
|
||||||
|
};
|
||||||
|
|
||||||
|
self.saveCallback(snapshotObject);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
done(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
show(src) {
|
||||||
|
this.painterroInstance = this.painterro.show(src);
|
||||||
|
}
|
||||||
|
}
|
@ -113,7 +113,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ViewSwitcher from './ViewSwitcher.vue';
|
import ViewSwitcher from './ViewSwitcher.vue';
|
||||||
import NotebookMenuSwitcher from '@/plugins/notebook/components/notebook-menu-switcher.vue';
|
import NotebookMenuSwitcher from '@/plugins/notebook/components/NotebookMenuSwitcher.vue';
|
||||||
|
|
||||||
const PLACEHOLDER_OBJECT = {};
|
const PLACEHOLDER_OBJECT = {};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user