Notebook Snapshot and Annotate (#2240)

Notebook Snapshots and Annotations from new Browse Bar
This commit is contained in:
Deep Tailor 2018-12-12 18:57:45 -08:00 committed by Andrew Henry
parent c0b7276787
commit 18a94d938f
19 changed files with 306 additions and 967 deletions

View File

@ -30,6 +30,7 @@ define([
"./src/controllers/CompositeController",
"./src/controllers/ColorController",
"./src/controllers/DialogButtonController",
"./src/controllers/SnapshotPreviewController",
"./res/templates/controls/autocomplete.html",
"./res/templates/controls/checkbox.html",
"./res/templates/controls/datetime.html",
@ -44,6 +45,7 @@ define([
"./res/templates/controls/dialog.html",
"./res/templates/controls/radio.html",
"./res/templates/controls/file-input.html",
"./res/templates/controls/snap-view.html",
'legacyRegistry'
], function (
MCTForm,
@ -55,6 +57,7 @@ define([
CompositeController,
ColorController,
DialogButtonController,
SnapshotPreviewController,
autocompleteTemplate,
checkboxTemplate,
datetimeTemplate,
@ -69,6 +72,7 @@ define([
dialogTemplate,
radioTemplate,
fileInputTemplate,
snapViewTemplate,
legacyRegistry
) {
@ -153,6 +157,10 @@ define([
{
"key": "file-input",
"template": fileInputTemplate
},
{
"key": "snap-view",
"template": snapViewTemplate
}
],
"controllers": [
@ -186,6 +194,14 @@ define([
"$scope",
"dialogService"
]
},
{
"key": "SnapshotPreviewController",
"implementation": SnapshotPreviewController,
"depends": [
"$scope",
"openmct"
]
}
],
"components": [

View File

@ -1,5 +1,5 @@
<!--
Open MCT, Copyright (c) 2014-2017, United States Government
Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
@ -19,11 +19,18 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class='form-control select' ng-controller="selectSnapshotController">
<select
ng-model="selectModel"
ng-options="opt.value as opt.name for opt in options"
ng-required="ngRequired"
name="mctControl">
</select>
</div>
<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>

View File

@ -0,0 +1,120 @@
/*****************************************************************************
* 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(
[
'painterro'
],
function (Painterro) {
function SnapshotPreviewController($scope, openmct) {
$scope.previewImage = function (imageUrl) {
var image = document.createElement('img');
image.src = imageUrl;
openmct.overlays.overlay(
{
element: image,
size: 'large'
}
);
};
$scope.annotateImage = function (ngModel, field, imageUrl) {
$scope.imageUrl = imageUrl;
var div = document.createElement('div'),
painterroInstance = {},
save = false;
div.id = 'snap-annotation';
openmct.overlays.overlay(
{
element: div,
size: 'large',
buttons: [
{
label: 'Cancel',
callback: function () {
save = false;
painterroInstance.save();
}
},
{
label: 'Save',
callback: function () {
save = true;
painterroInstance.save();
}
}
]
}
);
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) {
var 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;
}
);

View File

@ -21,27 +21,9 @@
*****************************************************************************/
define([
"./src/controllers/NotebookController",
"./src/controllers/NewEntryController",
"./src/controllers/SelectSnapshotController",
"./src/actions/NewEntryContextual",
"./src/actions/AnnotateSnapshot",
"./src/directives/MCTSnapshot",
"./res/templates/controls/snapSelect.html",
"./res/templates/controls/embedControl.html",
"./res/templates/annotation.html",
"./res/templates/draggedEntry.html"
"./src/controllers/NotebookController"
], function (
NotebookController,
NewEntryController,
SelectSnapshotController,
newEntryAction,
AnnotateSnapshotAction,
MCTSnapshotDirective,
snapSelectTemplate,
embedControlTemplate,
annotationTemplate,
draggedEntryTemplate
NotebookController
) {
var installed = false;
@ -87,90 +69,6 @@ define([
}
]
}
],
actions: [
{
"key": "notebook-new-entry",
"implementation": newEntryAction,
"name": "New Notebook Entry",
"cssClass": "icon-notebook labeled",
"description": "Add a new Notebook entry",
"category": [
"view-control"
],
"depends": [
"$compile",
"$rootScope",
"dialogService",
"notificationService",
"linkService"
],
"priority": "preferred"
},
{
"key": "annotate-snapshot",
"implementation": AnnotateSnapshotAction,
"name": "Annotate Snapshot",
"cssClass": "icon-pencil labeled",
"description": "Annotate embed's snapshot",
"category": "embed",
"depends": [
"dialogService",
"dndService",
"$rootScope"
]
}
],
controllers: [
{
"key": "NewEntryController",
"implementation": NewEntryController,
"depends": ["$scope",
"$rootScope"
]
},
{
"key": "selectSnapshotController",
"implementation": SelectSnapshotController,
"depends": ["$scope",
"$rootScope"
]
}
],
controls: [
{
"key": "snapshot-select",
"template": snapSelectTemplate
},
{
"key": "embed-control",
"template": embedControlTemplate
}
],
templates: [
{
"key": "annotate-snapshot",
"template": annotationTemplate
}
],
directives: [
{
"key": "mctSnapshot",
"implementation": MCTSnapshotDirective,
"depends": [
"$rootScope",
"$document",
"exportImageService",
"dialogService",
"notificationService"
]
}
],
representations: [
{
"key": "draggedEntry",
"template": draggedEntryTemplate
}
]
}
});

View File

@ -1,2 +0,0 @@
<div class="snap-annotation" id="snap-annotation" ng-controller="ngModel.controller">
</div>

View File

@ -1,51 +0,0 @@
<!--
Open MCT, Copyright (c) 2009-2016, 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.
-->
<!--
This element appears in the overlay dialog when initiating a new Notebook Entry from a view's Notebook button -->
<div class='form-control'>
<ng-form name="mctControl">
<div class='fields' ng-controller="NewEntryController">
<div class="l-flex-row new-notebook-entry-embed l-entry-embed {{cssClass}}"
ng-class="{ 'has-snapshot' : snapToggle }">
<div class="holder flex-elem snap-thumb"
ng-if="snapToggle">
<img ng-src="{{snapshot.src}}" alt="{{snapshot.modified}}">
</div>
<div class="holder flex-elem embed-info">
<div class="embed-title">{{objectName}}</div>
<div class="embed-date"
ng-if="snapToggle">{{snapshot.modified| date:'yyyy-MM-dd HH:mm:ss'}}</div>
</div>
<div class="holder flex-elem annotate-new"
ng-if="snapToggle">
<a class="s-button flex-elem icon-pencil "
title="Annotate this snapshot"
ng-click="annotateSnapshot()">
<span class="title-label">Annotate</span>
</a>
</div>
</div>
</div>
</ng-form>
</div>

View File

@ -1,38 +0,0 @@
<!--
Open MCT, Copyright (c) 2014-2017, 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.
-->
<div class="frame snap-frame frame-template t-frame-inner abs t-object-type-{{ representation.selected.key }}">
<div class="abs object-browse-bar l-flex-row">
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
<mct-representation
key="'switcher'"
ng-model="representation"
mct-object="domainObject">
</mct-representation>
</div>
</div>
<div class="abs object-holder" data-entry = "{{parameters.entry}}" data-embed = "{{parameters.embed}}" mct-snapshot ng-if="representation.selected.key">
<mct-representation
key="representation.selected.key"
mct-object="representation.selected.key && domainObject">
</mct-representation>
</div>
</div>

View File

@ -31,8 +31,9 @@
<div class="c-notebook__entries" ng-mouseover="handleActive()">
<ul>
<notebook-entry
v-for="entry in filteredAndSortedEntries"
v-bind:entry="entry">
v-for="(entry,index) in filteredAndSortedEntries"
:key="entry.key"
:entry="entry">
</notebook-entry>
</ul>
</div>

View File

@ -1,162 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, 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.
*****************************************************************************/
/**
* Module defining viewSnapshot (Originally NewWindowAction). Created by vwoeltje on 11/18/14.
*/
define(
["painterro", "zepto"],
function (Painterro, $) {
var annotationStruct = {
title: "Annotate Snapshot",
template: "annotate-snapshot",
options: [{
name: "OK",
key: "ok",
description: "save annotation"
},
{
name: "Cancel",
key: "cancel",
description: "cancel editing"
}]
};
function AnnotateSnapshot(dialogService, dndService, $rootScope, context) {
context = context || {};
// Choose the object to be opened into a new tab
this.domainObject = context.selectedObject || context.domainObject;
this.dialogService = dialogService;
this.dndService = dndService;
this.$rootScope = $rootScope;
}
AnnotateSnapshot.prototype.perform = function ($event, snapshot, embedId, entryId) {
var DOMAIN_OBJECT = this.domainObject;
var ROOTSCOPE = this.$rootScope;
var painterro;
var save = false;
var controller = ['$scope', '$timeout', function PainterroController($scope, $timeout) {
$(document.body).find('.l-dialog .outer-holder').addClass('annotation-dialog');
// Timeout is necessary because Painterro uses document.getElementById, and mct-include
// hasn't added the dialog to the DOM yet.
$timeout(function () {
painterro = 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) {
if (entryId && embedId) {
var elementPos = DOMAIN_OBJECT.model.entries.map(function (x) {
return x.createdOn;
}).indexOf(entryId);
var entryEmbeds = DOMAIN_OBJECT.model.entries[elementPos].embeds;
var embedPos = entryEmbeds.map(function (x) {
return x.id;
}).indexOf(embedId);
saveSnap(image.asBlob(), embedPos, elementPos, DOMAIN_OBJECT);
}else {
ROOTSCOPE.snapshot = {'src': image.asDataURL('image/png'),
'modified': Date.now()};
}
}
done(true);
}
}).show(snapshot);
});
}];
annotationStruct.model = {'controller': controller};
function saveNotes(param) {
if (param === 'ok') {
save = true;
}else {
save = false;
ROOTSCOPE.snapshot = "annotationCancelled";
}
painterro.save();
}
function rejectNotes() {
save = false;
ROOTSCOPE.snapshot = "annotationCancelled";
painterro.save();
}
function saveSnap(url, embedPos, entryPos, domainObject) {
var snap = false;
if (embedPos !== -1 && entryPos !== -1) {
var reader = new window.FileReader();
reader.readAsDataURL(url);
reader.onloadend = function () {
snap = reader.result;
domainObject.useCapability('mutation', function (model) {
if (model.entries[entryPos]) {
model.entries[entryPos].embeds[embedPos].snapshot = {
'src': snap,
'type': url.type,
'size': url.size,
'modified': Date.now()
};
model.entries[entryPos].embeds[embedPos].id = Date.now();
}
});
};
}
}
this.dialogService.getUserChoice(annotationStruct)
.then(saveNotes, rejectNotes);
};
return AnnotateSnapshot;
}
);

View File

@ -1,204 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, 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(
[],
function () {
var SNAPSHOT_TEMPLATE = '<mct-representation key="\'draggedEntry\'"' +
'class="t-rep-frame holder"' +
'mct-object="selObj">' +
'</mct-representation>';
var NEW_TASK_FORM = {
name: "Create a Notebook Entry",
hint: "Please select one Notebook",
sections: [{
rows: [{
name: 'Entry',
key: 'entry',
control: 'textarea',
required: false,
"cssClass": "l-textarea-sm"
},
{
name: 'Embed Type',
key: 'withSnapshot',
control: 'snapshot-select',
"options": [
{
"name": "Link and Snapshot",
"value": true
},
{
"name": "Link only",
"value": false
}
]
},
{
name: 'Embed',
key: 'embedObject',
control: 'embed-control'
},
{
name: 'Save in Notebook',
key: 'saveNotebook',
control: 'locator',
validate: validateLocation
}]
}]
};
function NewEntryContextual($compile, $rootScope, dialogService, notificationService, linkService, context) {
context = context || {};
this.domainObject = context.selectedObject || context.domainObject;
this.dialogService = dialogService;
this.notificationService = notificationService;
this.linkService = linkService;
this.$rootScope = $rootScope;
this.$compile = $compile;
}
function validateLocation(newParentObj) {
return newParentObj.model.type === 'notebook';
}
NewEntryContextual.prototype.perform = function () {
var self = this;
var domainObj = this.domainObject;
var notification = this.notificationService;
var dialogService = this.dialogService;
var rootScope = this.$rootScope;
rootScope.newEntryText = '';
// // Create the overlay element and add it to the document's body
this.$rootScope.selObj = domainObj;
this.$rootScope.selValue = "";
var newScope = rootScope.$new();
newScope.selObj = domainObj;
newScope.selValue = "";
this.$compile(SNAPSHOT_TEMPLATE)(newScope);
this.$rootScope.$watch("snapshot", setSnapshot);
function setSnapshot(value) {
if (value === "annotationCancelled") {
rootScope.snapshot = rootScope.lastValue;
rootScope.lastValue = '';
} else if (value && value !== rootScope.lastValue) {
var overlayModel = {
title: NEW_TASK_FORM.name,
message: NEW_TASK_FORM.message,
structure: NEW_TASK_FORM,
value: {'entry': rootScope.newEntryText || ""}
};
rootScope.currentDialog = overlayModel;
dialogService.getDialogResponse(
"overlay-dialog",
overlayModel,
function () {
return overlayModel.value;
}
).then(addNewEntry);
rootScope.lastValue = value;
}
}
function addNewEntry(options) {
options.selectedModel = options.embedObject.getModel();
options.cssClass = options.embedObject.getCapability('type').typeDef.cssClass;
if (self.$rootScope.snapshot) {
options.snapshot = self.$rootScope.snapshot;
self.$rootScope.snapshot = undefined;
}else {
options.snapshot = undefined;
}
if (!options.withSnapshot) {
options.snapshot = '';
}
createSnap(options);
}
function createSnap(options) {
options.saveNotebook.useCapability('mutation', function (model) {
var entries = model.entries;
var lastEntry = entries[entries.length - 1];
var date = Date.now();
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds) {
model.entries.push({
'id': date,
'createdOn': date,
'text': options.entry,
'embeds': [{'type': options.embedObject.getId(),
'id': '' + date,
'cssClass': options.cssClass,
'name': options.selectedModel.name,
'snapshot': options.snapshot
}]
});
}else {
model.entries[entries.length - 1] = {
'id': date,
'createdOn': date,
'text': options.entry,
'embeds': [{'type': options.embedObject.getId(),
'id': '' + date,
'cssClass': options.cssClass,
'name': options.selectedModel.name,
'snapshot': options.snapshot
}]
};
}
});
notification.info({
title: "Notebook Entry created"
});
}
};
NewEntryContextual.appliesTo = function (context) {
var domainObject = context.domainObject;
if (domainObject) {
if (domainObject.getModel().type === 'notebook') {
// do not allow in context of a notebook
return false;
} else if (domainObject.getModel().type.includes('imagery')) {
// do not allow in the context of an object with imagery
// (because of cross domain issue with snapshot)
return false;
}
}
return true;
};
return NewEntryContextual;
}
);

View File

@ -1,130 +0,0 @@
/*****************************************************************************
* 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(
['zepto'],
function ($) {
function SnapshotAction (exportImageService, dialogService, context) {
this.exportImageService = exportImageService;
this.dialogService = dialogService;
this.domainObject = context.domainObject;
}
SnapshotAction.prototype.perform = function () {
var elementToSnapshot =
$(document.body).find(".overlay .object-holder")[0] ||
$(document.body).find("[key='representation.selected.key']")[0];
$(elementToSnapshot).addClass("s-status-taking-snapshot");
this.exportImageService.exportPNGtoSRC(elementToSnapshot).then(function (blob) {
$(elementToSnapshot).removeClass("s-status-taking-snapshot");
if (blob) {
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
this.saveSnapshot(reader.result, blob.type, blob.size);
}.bind(this);
}
}.bind(this));
};
SnapshotAction.prototype.saveSnapshot = function (imageURL, imageType, imageSize) {
var taskForm = this.generateTaskForm(),
domainObject = this.domainObject,
domainObjectId = domainObject.getId(),
cssClass = domainObject.getCapability('type').typeDef.cssClass,
name = domainObject.model.name;
this.dialogService.getDialogResponse(
'overlay-dialog',
taskForm,
function () {
return taskForm.value;
}
).then(function (options) {
var snapshotObject = {
src: imageURL,
type: imageType,
size: imageSize
};
options.notebook.useCapability('mutation', function (model) {
var date = Date.now();
model.entries.push({
id: 'entry-' + date,
createdOn: date,
text: options.entry,
embeds: [{
name: name,
cssClass: cssClass,
type: domainObjectId,
id: 'embed-' + date,
createdOn: date,
snapshot: snapshotObject
}]
});
});
});
};
SnapshotAction.prototype.generateTaskForm = function () {
var taskForm = {
name: "Create a Notebook Entry",
hint: "Please select a Notebook",
sections: [{
rows: [{
name: 'Entry',
key: 'entry',
control: 'textarea',
required: false,
"cssClass": "l-textarea-sm"
},
{
name: 'Save in Notebook',
key: 'notebook',
control: 'locator',
validate: validateLocation
}]
}]
};
var overlayModel = {
title: taskForm.name,
message: 'AHAHAH',
structure: taskForm,
value: {'entry': ""}
};
function validateLocation(newParentObj) {
return newParentObj.model.type === 'notebook';
}
return overlayModel;
};
return SnapshotAction;
}
);

View File

@ -275,7 +275,6 @@ function (
function menuClickHandler(e) {
e.stopPropagation();
window.setTimeout(dismiss, 300);
}
// Dismiss any menu which was already showing

View File

@ -1,65 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, 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.
*****************************************************************************/
/**
* Module defining NewEntryController. */
define(
[],
function () {
function NewEntryController($scope,$rootScope) {
$scope.snapshot = undefined;
$scope.snapToggle = true;
$scope.entryText = '';
var annotateAction = $rootScope.selObj.getCapability('action').getActions({key: 'annotate-snapshot'})[0];
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = $rootScope.selObj;
$scope.objectName = $rootScope.selObj.getModel().name;
$scope.cssClass = $rootScope.selObj.getCapability('type').typeDef.cssClass;
$scope.annotateSnapshot = function ($event) {
if ($rootScope.currentDialog.value) {
$rootScope.newEntryText = $scope.$parent.$parent.ngModel.entry;
$rootScope.currentDialog.cancel();
annotateAction.perform($event, $rootScope.snapshot.src);
$rootScope.currentDialog = undefined;
}
};
function updateSnapshot(img) {
$scope.snapshot = img;
}
// Update set of actions whenever the action capability
// changes or becomes available.
$rootScope.$watch("snapshot", updateSnapshot);
$rootScope.$watch("selValue", toggleEmbed);
function toggleEmbed(value) {
$scope.snapToggle = value;
}
}
return NewEntryController;
}
);

View File

@ -1,44 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, 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.
*****************************************************************************/
/**
* Module defining SelectSnapshotController. */
define(
[],
function () {
function SelectSnapshotController($scope,$rootScope) {
$scope.selectModel = true;
function selectprint(value) {
$rootScope.selValue = value;
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = value;
}
$scope.$watch("selectModel", selectprint);
}
return SelectSnapshotController;
}
);

View File

@ -1,86 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2016, 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(['zepto'], function ($) {
function MCTSnapshot($rootScope, $document, exportImageService, dialogService, notificationService) {
var document = $document[0];
function link($scope, $element, $attrs) {
var objectElement = $(document.body).find(".overlay .object-holder")[0] || $(document.body).find("[key='representation.selected.key']")[0],
takeSnapshot,
makeImg,
saveImg;
$(objectElement).addClass("s-status-taking-snapshot");
saveImg = function (url, entryId, embedId) {
$scope.$parent.$parent.$parent.saveSnap(url, embedId, entryId);
};
makeImg = function (el) {
var scope = $scope;
exportImageService.exportPNGtoSRC(el).then(function (img) {
$(objectElement).removeClass("s-status-taking-snapshot");
if (img) {
if ($element[0].dataset.entry && $element[0].dataset.embed) {
saveImg(img, +$element[0].dataset.entry, +$element[0].dataset.embed);
} else {
var reader = new window.FileReader();
reader.readAsDataURL(img);
reader.onloadend = function () {
$($element[0]).attr("data-snapshot", reader.result);
$rootScope.snapshot = {
'src': reader.result,
'type': img.type,
'size': img.size,
'modified': Date.now()
};
scope.$destroy();
};
}
}
});
};
takeSnapshot = function () {
makeImg(objectElement);
};
takeSnapshot();
$scope.$on('$destroy', function () {
$element.remove();
});
}
return {
restrict: 'A',
link: link
};
}
return MCTSnapshot;
});

View File

@ -1,66 +0,0 @@
/*****************************************************************************
* 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',
'../../res/templates/viewSnapshot.html'
], function (
Vue,
snapshotOverlayTemplate
) {
function SnapshotOverlay (embedObject, formatTime) {
this.embedObject = embedObject;
this.snapshotOverlayVue = new Vue({
template: snapshotOverlayTemplate,
data: function () {
return {
embed: embedObject
};
},
methods: {
close: this.close.bind(this),
formatTime: formatTime
}
});
this.open();
}
SnapshotOverlay.prototype.open = function () {
this.overlay = document.createElement('div');
this.overlay.classList.add('abs');
document.body.appendChild(this.overlay);
this.overlay.appendChild(this.snapshotOverlayVue.$mount().$el);
};
SnapshotOverlay.prototype.close = function (event) {
event.stopPropagation();
this.snapshotOverlayVue.$destroy();
this.overlay.parentNode.removeChild(this.overlay);
};
return SnapshotOverlay;
});

View File

@ -137,8 +137,8 @@ define(
* @returns {promise}
*/
ExportImageService.prototype.exportPNGtoSRC = function (element) {
return this.renderElement(element, "png");
ExportImageService.prototype.exportPNGtoSRC = function (element, className) {
return this.renderElement(element, "png", className);
};
/**

View File

@ -39,7 +39,10 @@
</div>
<!-- Action buttons -->
<div class="l-browse-bar__actions">
<button class="l-browse-bar__actions__edit c-button icon-notebook" title="New Notebook entry"></button>
<button class="l-browse-bar__actions__edit c-button icon-notebook"
title="New Notebook entry"
@click="snapshot()">
</button>
<button class="l-browse-bar__actions__notebook-entry c-button c-button--major icon-pencil" title="Edit" v-if="!isEditing" @click="edit()"></button>
<button class="l-browse-bar__actions c-button c-button--major icon-save" title="Save and Finish Editing" v-if="isEditing" @click="saveAndFinishEditing()"></button>
<button class="l-browse-bar__actions c-button icon-x" title="Cancel Editing" v-if="isEditing" @click="cancelEditing()"></button>
@ -49,6 +52,8 @@
</template>
<script>
import NotebookSnapshot from '../utils/notebook-snapshot';
export default {
inject: ['openmct'],
methods: {
@ -86,6 +91,10 @@
event.preventDefault();
event.stopPropagation();
this.openmct.contextMenu._showContextMenuForObjectPath(this.openmct.router.path, event.clientX, event.clientY);
},
snapshot() {
let element = document.getElementsByClassName("l-shell__main-container")[0];
this.notebookSnapshot.capture(this.domainObject, element);
}
},
data: function () {
@ -122,6 +131,8 @@
}
},
mounted: function () {
this.notebookSnapshot = new NotebookSnapshot(this.openmct);
document.addEventListener('click', () => {
if (this.showViewMenu) {
this.showViewMenu = false;

View File

@ -0,0 +1,135 @@
/*****************************************************************************
* 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.
*****************************************************************************/
class NotebookSnapshot {
constructor(openmct) {
this.openmct = openmct;
this.exportImageService = openmct.$injector.get('exportImageService');
this.dialogService = openmct.$injector.get('dialogService');
this.capture = this.capture.bind(this);
this._saveSnapShot = this._saveSnapShot.bind(this);
}
capture(domainObject, domElement) {
let type = this.openmct.types.get(domainObject.type),
embedObject = {
id: domainObject.identifier.key,
cssClass: type.cssClass,
name: domainObject.name
};
this.exportImageService.exportPNGtoSRC(domElement, 's-status-taking-snapshot').then(function (blob) {
var reader = new window.FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function () {
this._saveSnapShot(reader.result, embedObject);
}.bind(this);
}.bind(this));
}
/**
* @private
*/
_generateTaskForm(url) {
var taskForm = {
name: "Create a Notebook Entry",
hint: "Please select a Notebook",
sections: [{
rows: [
{
name: 'Entry',
key: 'entry',
control: 'textarea',
required: false,
cssClass: "l-textarea-sm"
},
{
name: 'Snap Preview',
key:"snapPreview",
control: "snap-view",
cssClass: "l-textarea-sm",
src: url
},
{
name: 'Save in Notebook',
key: 'notebook',
control: 'locator',
validate: validateLocation
}
]
}]
};
var overlayModel = {
title: taskForm.name,
message: 'Notebook Snapshot',
structure: taskForm,
value: {'entry': ""}
};
function validateLocation(newParentObj) {
return newParentObj.model.type === 'notebook';
}
return overlayModel;
}
/**
* @private
*/
_saveSnapShot(imageUrl, embedObject) {
let taskForm = this._generateTaskForm(imageUrl);
this.dialogService.getDialogResponse(
'overlay-dialog',
taskForm,
() => taskForm.value
).then(options => {
let snapshotObject = {
src: options.snapPreview || imageUrl
};
options.notebook.useCapability('mutation', function (model) {
var date = Date.now();
model.entries.push({
id: 'entry-' + date,
createdOn: date,
text: options.entry,
embeds: [{
name: embedObject.name,
cssClass: embedObject.cssClass,
type: embedObject.id,
id: 'embed-' + date,
createdOn: date,
snapshot: snapshotObject
}]
});
});
});
}
}
export default NotebookSnapshot;