mirror of
https://github.com/nasa/openmct.git
synced 2025-07-01 21:01:11 +00:00
Compare commits
41 Commits
vue-main-s
...
vue-toolba
Author | SHA1 | Date | |
---|---|---|---|
0b828b68a3 | |||
76c21ba73a | |||
d35800a307 | |||
ebd266cbbb | |||
de900702a6 | |||
ae8202b90e | |||
84350d1776 | |||
88a23151ec | |||
1a60a2e13a | |||
6e81b985a6 | |||
0ee881f2d2 | |||
908b843d8b | |||
16df2567ed | |||
1aea27f9b6 | |||
0d1acfd4df | |||
13c984f3c1 | |||
f8aea00792 | |||
15c52fe097 | |||
1b4aa5cbbf | |||
11acc1cfe5 | |||
d4c2a44a96 | |||
7792396c46 | |||
984cf0ca1e | |||
7483e886f1 | |||
792633c0d1 | |||
dfd33251f0 | |||
734d368c0b | |||
794098740e | |||
9c178a870d | |||
8b3a058b03 | |||
ef92da4d9d | |||
80b02672a6 | |||
fbf1c68c7a | |||
5eac6e646b | |||
82e5bf2325 | |||
40b7117987 | |||
07ca60e13a | |||
08cd6b1d99 | |||
78ae7b334c | |||
3a28caac06 | |||
c883bbe6c2 |
2
app.js
2
app.js
@ -46,7 +46,7 @@ webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
|
|||||||
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
|
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
|
||||||
|
|
||||||
webpackConfig.entry.openmct = [
|
webpackConfig.entry.openmct = [
|
||||||
'webpack-hot-middleware/client',
|
'webpack-hot-middleware/client?reload=true',
|
||||||
webpackConfig.entry.openmct
|
webpackConfig.entry.openmct
|
||||||
];
|
];
|
||||||
|
|
||||||
|
21
copyright-notice.html
Normal file
21
copyright-notice.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
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.
|
||||||
|
-->
|
@ -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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -19,26 +19,3 @@
|
|||||||
* this source code distribution or the Licensing information page available
|
* this source code distribution or the Licensing information page available
|
||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* This bundle implements "containment" rules, which determine which objects
|
|
||||||
* can be contained within a notebook.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
function CompositionPolicy() {
|
|
||||||
}
|
|
||||||
|
|
||||||
CompositionPolicy.prototype.allow = function (parent, child) {
|
|
||||||
var parentDef = parent.getCapability('type').getName();
|
|
||||||
|
|
||||||
if (parentDef === 'Notebook' && child.getCapability('status').list().length) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
return CompositionPolicy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -55,7 +55,7 @@ define(
|
|||||||
|
|
||||||
// A view is editable unless explicitly flagged as not
|
// A view is editable unless explicitly flagged as not
|
||||||
(views || []).forEach(function (view) {
|
(views || []).forEach(function (view) {
|
||||||
if (view.editable === true ||
|
if (isEditable(view) ||
|
||||||
(view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
|
(view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
|
||||||
(view.key === 'table' && type.getKey() === 'table') ||
|
(view.key === 'table' && type.getKey() === 'table') ||
|
||||||
(view.key === 'rt-table' && type.getKey() === 'rttable')
|
(view.key === 'rt-table' && type.getKey() === 'rttable')
|
||||||
@ -64,6 +64,14 @@ define(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function isEditable(view) {
|
||||||
|
if (typeof view.editable === Function) {
|
||||||
|
return view.editable(domainObject.useCapability('adapter'));
|
||||||
|
} else {
|
||||||
|
return view.editable === true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,294 +0,0 @@
|
|||||||
define([
|
|
||||||
"legacyRegistry",
|
|
||||||
"./src/controllers/NotebookController",
|
|
||||||
"./src/controllers/NewEntryController",
|
|
||||||
"./src/controllers/SelectSnapshotController",
|
|
||||||
"./src/controllers/LayoutNotebookController",
|
|
||||||
"./src/directives/MCTSnapshot",
|
|
||||||
"./src/directives/EntryDnd",
|
|
||||||
"./src/actions/ViewSnapshot",
|
|
||||||
"./src/actions/AnnotateSnapshot",
|
|
||||||
"./src/actions/RemoveEmbed",
|
|
||||||
"./src/actions/RemoveSnapshot",
|
|
||||||
"./src/actions/NewEntryContextual",
|
|
||||||
"./src/capabilities/NotebookCapability",
|
|
||||||
"./src/policies/CompositionPolicy",
|
|
||||||
"./res/templates/notebook.html",
|
|
||||||
"./res/templates/entry.html",
|
|
||||||
"./res/templates/annotation.html",
|
|
||||||
"./res/templates/notifications.html",
|
|
||||||
"../layout/res/templates/frame.html",
|
|
||||||
"./res/templates/controls/embedControl.html",
|
|
||||||
"./res/templates/controls/snapSelect.html"
|
|
||||||
], function (
|
|
||||||
legacyRegistry,
|
|
||||||
NotebookController,
|
|
||||||
NewEntryController,
|
|
||||||
SelectSnapshotController,
|
|
||||||
LayoutNotebookController,
|
|
||||||
MCTSnapshot,
|
|
||||||
MCTEntryDnd,
|
|
||||||
ViewSnapshotAction,
|
|
||||||
AnnotateSnapshotAction,
|
|
||||||
RemoveEmbedAction,
|
|
||||||
RemoveSnapshotAction,
|
|
||||||
newEntryAction,
|
|
||||||
NotebookCapability,
|
|
||||||
CompositionPolicy,
|
|
||||||
notebookTemplate,
|
|
||||||
entryTemplate,
|
|
||||||
annotationTemplate,
|
|
||||||
notificationsTemplate,
|
|
||||||
frameTemplate,
|
|
||||||
embedControlTemplate,
|
|
||||||
snapSelectTemplate
|
|
||||||
) {
|
|
||||||
legacyRegistry.register("platform/features/notebook", {
|
|
||||||
"name": "Notebook Plugin",
|
|
||||||
"description": "Create and save timestamped notes with embedded object snapshots.",
|
|
||||||
"extensions":
|
|
||||||
{
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"key": "notebook",
|
|
||||||
"name": "Notebook",
|
|
||||||
"cssClass": "icon-notebook",
|
|
||||||
"description": "Create and save timestamped notes with embedded object snapshots.",
|
|
||||||
"features": ["creation"],
|
|
||||||
"model": {
|
|
||||||
"entries": [],
|
|
||||||
"composition": [],
|
|
||||||
"entryTypes": [],
|
|
||||||
"defaultSort": "-createdOn"
|
|
||||||
},
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"key": "defaultSort",
|
|
||||||
"name": "Default Sort",
|
|
||||||
"control": "select",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"name": "Newest First",
|
|
||||||
"value": "-createdOn"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Oldest First",
|
|
||||||
"value": "createdOn"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"cssClass": "l-inline"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [
|
|
||||||
{
|
|
||||||
"key": "notebook.view",
|
|
||||||
"type": "notebook",
|
|
||||||
"cssClass": "icon-notebook",
|
|
||||||
"name": "notebook",
|
|
||||||
"template": notebookTemplate,
|
|
||||||
"editable": false,
|
|
||||||
"uses": [
|
|
||||||
"composition",
|
|
||||||
"action"
|
|
||||||
],
|
|
||||||
"gestures": [
|
|
||||||
"drop"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controllers": [
|
|
||||||
{
|
|
||||||
"key": "NotebookController",
|
|
||||||
"implementation": NotebookController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"dialogService",
|
|
||||||
"popupService",
|
|
||||||
"agentService",
|
|
||||||
"objectService",
|
|
||||||
"navigationService",
|
|
||||||
"now",
|
|
||||||
"actionService",
|
|
||||||
"$timeout",
|
|
||||||
"$element",
|
|
||||||
"$sce"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "NewEntryController",
|
|
||||||
"implementation": NewEntryController,
|
|
||||||
"depends": ["$scope",
|
|
||||||
"$rootScope"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "selectSnapshotController",
|
|
||||||
"implementation": SelectSnapshotController,
|
|
||||||
"depends": ["$scope",
|
|
||||||
"$rootScope"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "LayoutNotebookController",
|
|
||||||
"implementation": LayoutNotebookController,
|
|
||||||
"depends": ["$scope"]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"representations": [
|
|
||||||
{
|
|
||||||
"key": "draggedEntry",
|
|
||||||
"template": entryTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "frameLayoutNotebook",
|
|
||||||
"template": frameTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"templates": [
|
|
||||||
{
|
|
||||||
"key": "annotate-snapshot",
|
|
||||||
"template": annotationTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "notificationTemplate",
|
|
||||||
"template": notificationsTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"directives": [
|
|
||||||
{
|
|
||||||
"key": "mctSnapshot",
|
|
||||||
"implementation": MCTSnapshot,
|
|
||||||
"depends": [
|
|
||||||
"$rootScope",
|
|
||||||
"$document",
|
|
||||||
"exportImageService",
|
|
||||||
"dialogService",
|
|
||||||
"notificationService"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "mctEntryDnd",
|
|
||||||
"implementation": MCTEntryDnd,
|
|
||||||
"depends": [
|
|
||||||
"$rootScope",
|
|
||||||
"$compile",
|
|
||||||
"dndService",
|
|
||||||
"typeService",
|
|
||||||
"notificationService"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"actions": [
|
|
||||||
{
|
|
||||||
"key": "view-snapshot",
|
|
||||||
"implementation": ViewSnapshotAction,
|
|
||||||
"name": "View Snapshot",
|
|
||||||
"description": "View the large image in a modal",
|
|
||||||
"category": "embed",
|
|
||||||
"depends": [
|
|
||||||
"$compile"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "annotate-snapshot",
|
|
||||||
"implementation": AnnotateSnapshotAction,
|
|
||||||
"name": "Annotate Snapshot",
|
|
||||||
"cssClass": "icon-pencil labeled",
|
|
||||||
"description": "Annotate embed's snapshot",
|
|
||||||
"category": "embed",
|
|
||||||
"depends": [
|
|
||||||
"dialogService",
|
|
||||||
"dndService",
|
|
||||||
"$rootScope"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
"key": "remove-embed",
|
|
||||||
"implementation": RemoveEmbedAction,
|
|
||||||
"name": "Remove...",
|
|
||||||
"cssClass": "icon-trash labeled",
|
|
||||||
"description": "Remove this embed",
|
|
||||||
"category": [
|
|
||||||
"embed",
|
|
||||||
"embed-no-snap"
|
|
||||||
],
|
|
||||||
"depends": [
|
|
||||||
"dialogService"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "remove-snapshot",
|
|
||||||
"implementation": RemoveSnapshotAction,
|
|
||||||
"name": "Remove Snapshot",
|
|
||||||
"cssClass": "icon-trash labeled",
|
|
||||||
"description": "Remove Snapshot of the embed",
|
|
||||||
"category": "embed",
|
|
||||||
"depends": [
|
|
||||||
"dialogService"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"licenses": [
|
|
||||||
{
|
|
||||||
"name": "painterro",
|
|
||||||
"version": "0.2.65",
|
|
||||||
"author": "Ivan Borshchov",
|
|
||||||
"description": "Painterro is JavaScript paint widget which allows editing images directly in a browser.",
|
|
||||||
"website": "https://github.com/ivictbor/painterro",
|
|
||||||
"copyright": "Copyright 2017 Ivan Borshchov",
|
|
||||||
"license": "MIT",
|
|
||||||
"link": "https://github.com/ivictbor/painterro/blob/master/LICENSE"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"capabilities": [
|
|
||||||
{
|
|
||||||
"key": "notebook",
|
|
||||||
"name": "Notebook Capability",
|
|
||||||
"description": "Provides a capability for looking for a notebook domain object",
|
|
||||||
"implementation": NotebookCapability,
|
|
||||||
"depends": [
|
|
||||||
"typeService"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"policies": [
|
|
||||||
{
|
|
||||||
"category": "composition",
|
|
||||||
"implementation": CompositionPolicy,
|
|
||||||
"message": "Objects of this type cannot contain objects of that type."
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controls": [
|
|
||||||
{
|
|
||||||
"key": "embed-control",
|
|
||||||
"template": embedControlTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "snapshot-select",
|
|
||||||
"template": snapSelectTemplate
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,118 +0,0 @@
|
|||||||
<div ng-controller="NotebookController as controller" class="mct-notebook w-notebook l-flex-col">
|
|
||||||
<div class="l-notebook-head holder l-flex-row flex-elem">
|
|
||||||
<div class="c-search flex-elem holder grows">
|
|
||||||
<input class="c-search__search-input"
|
|
||||||
type="text" tabindex="10000"
|
|
||||||
ng-model="entrySearch"
|
|
||||||
ng-keyup="controller.search()"/>
|
|
||||||
<a class="c-search__clear-input clear-icon icon-x-in-circle"
|
|
||||||
ng-class="{show: !(entrySearch === '' || entrySearch === undefined)}"
|
|
||||||
ng-click="entrySearch = ''; controller.search()"></a>
|
|
||||||
</div>
|
|
||||||
<div class="notebook-view-controls l-flex-row flex-elem holder">
|
|
||||||
<div class="select notebook-view-controls__filter-time">
|
|
||||||
<select ng-model="showTime">
|
|
||||||
<option value="0" selected="selected">Show all</option>
|
|
||||||
<option value="1">Last hour</option>
|
|
||||||
<option value="8">Last 8 hours</option>
|
|
||||||
<option value="24">Last 24 hours</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="select notebook-view-controls__sort">
|
|
||||||
<select ng-model="sortEntries">
|
|
||||||
<option value="-createdOn" selected="selected">Newest first</option>
|
|
||||||
<option value="createdOn">Oldest first</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- drag area -->
|
|
||||||
<div class="holder flex-elem l-flex-row icon-plus labeled l-notebook-drag-area" ng-click="newEntry($event)"
|
|
||||||
id="newEntry" mct-entry-dnd>
|
|
||||||
<span class="label">To start a new entry, click here or drag and drop any object</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- entries -->
|
|
||||||
<div class="holder flex-elem grows w-notebook-entries t-entries-list" ng-mouseover="handleActive()">
|
|
||||||
<ul>
|
|
||||||
<li class="l-flex-row has-local-controls l-notebook-entry s-notebook-entry"
|
|
||||||
id="{{'entry_'+ entry.id}}"
|
|
||||||
ng-if="hoursFilter(showTime,entry.createdOn)"
|
|
||||||
ng-repeat="entry in model.entries | filter:entrySearch | orderBy: sortEntries track by $index"
|
|
||||||
ng-init="$last && finished(model.entries)"
|
|
||||||
mct-entry-dnd>
|
|
||||||
<div class="holder flex-elem l-flex-row grows w-notebook-entry-time-and-content">
|
|
||||||
<div class="holder flex-elem s-notebook-entry-time">
|
|
||||||
<span>{{entry.createdOn | date:'yyyy-MM-dd'}}</span>
|
|
||||||
<span>{{entry.createdOn | date:'HH:mm:ss'}}</span>
|
|
||||||
</div>
|
|
||||||
<div class="holder flex-elem l-flex-col grows l-notebook-entry-content">
|
|
||||||
<div contenteditable="true"
|
|
||||||
ng-blur="textBlur($event, entry.id)"
|
|
||||||
ng-focus="textFocus($event, entry.id)"
|
|
||||||
ng-model="entry.text"
|
|
||||||
placeholder="Enter text here"
|
|
||||||
class="flex-elem s-input-inline t-notebook-entry-input s-notebook-entry-text"
|
|
||||||
ng-bind="entry.text">
|
|
||||||
</div>
|
|
||||||
<!-- embeds -->
|
|
||||||
<div class="flex-elem entry-embeds l-flex-row">
|
|
||||||
<div class="l-flex-row l-entry-embed {{embed.cssClass}}"
|
|
||||||
ng-repeat="embed in entry.embeds track by $index"
|
|
||||||
ng-class="{ 'has-snapshot' : embed.snapshot }"
|
|
||||||
id="{{embed.id}}">
|
|
||||||
<div class="snap-thumb"
|
|
||||||
ng-if="embed.snapshot"
|
|
||||||
ng-click="viewSnapshot($event,embed.snapshot.src,embed.id,entry.createdOn,this,embed)">
|
|
||||||
<img ng-src="{{embed.snapshot.src}}" src="//:0" alt="{{embed.id}}">
|
|
||||||
</div>
|
|
||||||
<div class="embed-info l-flex-col">
|
|
||||||
<div class="embed-title object-header">
|
|
||||||
<a ng-click='navigate($event,embed.type)'>{{embed.name}}</a>
|
|
||||||
<a class='context-available' ng-click='openMenu($event,embed.type)'></a>
|
|
||||||
</div>
|
|
||||||
<div class="hide-menu" ng-show="false">
|
|
||||||
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
|
||||||
<div class="menu context-menu">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="menu in menuEmbed"
|
|
||||||
ng-click="menu.perform($event,embed.snapshot.src,embed.id,entry.createdOn,this,embed)"
|
|
||||||
title="{{menu.getMetadata().description}}"
|
|
||||||
class="{{menu.getMetadata().cssClass}}"
|
|
||||||
ng-if="embed.snapshot">
|
|
||||||
{{menu.getMetadata().name}}
|
|
||||||
</li>
|
|
||||||
<li ng-repeat="menu in menuEmbedNoSnap"
|
|
||||||
ng-click="menu.perform($event,embed.snapshot.src,embed.id,entry.createdOn,this)"
|
|
||||||
title="{{menu.getMetadata().description}}"
|
|
||||||
class="{{menu.getMetadata().cssClass}}"
|
|
||||||
ng-if="!embed.snapshot">
|
|
||||||
{{menu.getMetadata().name}}
|
|
||||||
</li>
|
|
||||||
<li ng-repeat="menu in embedActions"
|
|
||||||
ng-click="menu.perform()"
|
|
||||||
title="{{menu.name}}"
|
|
||||||
class="{{menu.cssClass}}">
|
|
||||||
{{menu.name}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="embed-date"
|
|
||||||
ng-if="embed.snapshot">{{embed.id| date:'yyyy-MM-dd HH:mm:ss'}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- delete entry -->
|
|
||||||
<div class="holder flex-elem local-control local-controls-hidden notebook-entry-delete">
|
|
||||||
<a class="s-icon-button icon-trash" id={{entry.id}} title="Delete Entry" ng-click="deleteEntry($event)"></a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,8 +0,0 @@
|
|||||||
<span class="status block">
|
|
||||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
|
||||||
<span class="status-indicator icon-bell"></span>
|
|
||||||
<span class="label">
|
|
||||||
Notifications
|
|
||||||
</span>
|
|
||||||
<span class="count"></span>
|
|
||||||
</span>
|
|
@ -1,34 +0,0 @@
|
|||||||
<div class="t-snapshot abs l-view-header">
|
|
||||||
<div class="abs object-browse-bar l-flex-row">
|
|
||||||
<div class="left flex-elem l-flex-row grows">
|
|
||||||
<div class="object-header flex-elem l-flex-row grows">
|
|
||||||
<div class="type-icon flex-elem embed-icon holder" ng-class="cssClass"></div>
|
|
||||||
<div class="title-label flex-elem holder flex-can-shrink">{{entryName}}</div>
|
|
||||||
<a class="context-available flex-elem holder" ng-click="openMenu($event,embedType)"></a>
|
|
||||||
<div class="hide-menu" ng-show="false">
|
|
||||||
<div class="menu-element menu-view context-menu-wrapper mobile-disable-select">
|
|
||||||
<div class="menu context-menu">
|
|
||||||
<ul>
|
|
||||||
<li ng-repeat="menu in embedActions"
|
|
||||||
ng-click="menuPerform(menu)"
|
|
||||||
title="{{menu.name}}"
|
|
||||||
class="{{menu.cssClass}}">
|
|
||||||
{{menu.name}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
|
||||||
<div class="flex-elem holder flex-can-shrink s-snapshot-datetime">
|
|
||||||
SNAPSHOT {{snapDate | date:'yyyy-MM-dd HH:mm:ss'}}
|
|
||||||
</div>
|
|
||||||
<a class="s-button icon-pencil" title="Annotate">
|
|
||||||
<span class="title-label">Annotate</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,72 +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 () {
|
|
||||||
|
|
||||||
function RemoveEmbed(dialogService,context) {
|
|
||||||
context = context || {};
|
|
||||||
|
|
||||||
this.domainObject = context.selectedObject || context.domainObject;
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RemoveEmbed.prototype.perform = function ($event,snapshot,embedId,entryId) {
|
|
||||||
var domainObject = this.domainObject;
|
|
||||||
var errorDialog = this.dialogService.showBlockingMessage({
|
|
||||||
severity: "error",
|
|
||||||
title: "This action will permanently delete this Embed. Do you want to continue?",
|
|
||||||
minimized: true, // want the notification to be minimized initially (don't show banner)
|
|
||||||
options: [{
|
|
||||||
label: "OK",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
label: "Cancel",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
function remove() {
|
|
||||||
domainObject.useCapability('mutation', function (model) {
|
|
||||||
var elementPos = model.entries.map(function (x) {
|
|
||||||
return x.createdOn;
|
|
||||||
}).indexOf(entryId);
|
|
||||||
var entryEmbeds = model.entries[elementPos].embeds;
|
|
||||||
var embedPos = entryEmbeds.map(function (x) {
|
|
||||||
return x.id;
|
|
||||||
}).indexOf(embedId);
|
|
||||||
model.entries[elementPos].embeds.splice(embedPos, 1);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return RemoveEmbed;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,74 +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 () {
|
|
||||||
|
|
||||||
function RemoveSnapshot(dialogService, context) {
|
|
||||||
context = context || {};
|
|
||||||
|
|
||||||
this.domainObject = context.selectedObject || context.domainObject;
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
RemoveSnapshot.prototype.perform = function ($event, snapshot, embedId, entryId) {
|
|
||||||
|
|
||||||
var domainObject = this.domainObject;
|
|
||||||
var errorDialog = this.dialogService.showBlockingMessage({
|
|
||||||
severity: "error",
|
|
||||||
title: "This action will permanently delete this Snapshot. Do you want to continue?",
|
|
||||||
minimized: true, // want the notification to be minimized initially (don't show banner)
|
|
||||||
options: [{
|
|
||||||
label: "OK",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
remove();
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
label: "Cancel",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
|
|
||||||
function remove() {
|
|
||||||
domainObject.useCapability('mutation', function (model) {
|
|
||||||
var elementPos = model.entries.map(function (x) {
|
|
||||||
return x.createdOn;
|
|
||||||
}).indexOf(entryId);
|
|
||||||
var entryEmbeds = model.entries[elementPos].embeds;
|
|
||||||
var embedPos = entryEmbeds.map(function (x) {
|
|
||||||
return x.id;
|
|
||||||
}).indexOf(embedId);
|
|
||||||
model.entries[elementPos].embeds[embedPos].snapshot = "";
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
return RemoveSnapshot;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,132 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
var OVERLAY_TEMPLATE = '' +
|
|
||||||
' <div class="abs blocker"></div>' +
|
|
||||||
' <div class="abs outer-holder">' +
|
|
||||||
' <a class="close icon-x-in-circle"></a>' +
|
|
||||||
' <div class="abs inner-holder l-flex-col">' +
|
|
||||||
' <div class="t-contents flex-elem holder grows"></div>' +
|
|
||||||
' <div class="bottom-bar flex-elem holder">' +
|
|
||||||
' <a class="t-done s-button major">Done</a>' +
|
|
||||||
' </div>' +
|
|
||||||
' </div>' +
|
|
||||||
' </div>';
|
|
||||||
|
|
||||||
define([
|
|
||||||
'zepto',
|
|
||||||
"../../res/templates/snapshotHeader.html"
|
|
||||||
],
|
|
||||||
function ($, headerTemplate) {
|
|
||||||
|
|
||||||
var toggleOverlay,
|
|
||||||
overlay,
|
|
||||||
closeButton,
|
|
||||||
doneButton,
|
|
||||||
blocker,
|
|
||||||
overlayContainer,
|
|
||||||
img,
|
|
||||||
annotateButton,
|
|
||||||
annotateImg;
|
|
||||||
|
|
||||||
function ViewSnapshot($compile) {
|
|
||||||
this.$compile = $compile;
|
|
||||||
}
|
|
||||||
|
|
||||||
function openOverlay(url, header) {
|
|
||||||
overlay = document.createElement('div');
|
|
||||||
$(overlay).addClass('abs overlay l-large-view');
|
|
||||||
overlay.innerHTML = OVERLAY_TEMPLATE;
|
|
||||||
overlayContainer = overlay.querySelector('.t-contents');
|
|
||||||
closeButton = overlay.querySelector('a.close');
|
|
||||||
closeButton.addEventListener('click', toggleOverlay);
|
|
||||||
doneButton = overlay.querySelector('a.t-done');
|
|
||||||
doneButton.addEventListener('click', toggleOverlay);
|
|
||||||
blocker = overlay.querySelector('.abs.blocker');
|
|
||||||
blocker.addEventListener('click', toggleOverlay);
|
|
||||||
annotateButton = header.querySelector('a.icon-pencil');
|
|
||||||
annotateButton.addEventListener('click', annotateImg);
|
|
||||||
document.body.appendChild(overlay);
|
|
||||||
img = document.createElement('div');
|
|
||||||
$(img).addClass('abs object-holder t-image-holder s-image-holder');
|
|
||||||
img.innerHTML = '<div class="image-main s-image-main" style="background-image: url(' + url + ');"></div>';
|
|
||||||
overlayContainer.appendChild(header);
|
|
||||||
overlayContainer.appendChild(img);
|
|
||||||
}
|
|
||||||
|
|
||||||
function closeOverlay() {
|
|
||||||
overlayContainer.removeChild(img);
|
|
||||||
document.body.removeChild(overlay);
|
|
||||||
closeButton.removeEventListener('click', toggleOverlay);
|
|
||||||
closeButton = undefined;
|
|
||||||
doneButton.removeEventListener('click', toggleOverlay);
|
|
||||||
doneButton = undefined;
|
|
||||||
blocker.removeEventListener('click', toggleOverlay);
|
|
||||||
blocker = undefined;
|
|
||||||
overlayContainer = undefined;
|
|
||||||
overlay = undefined;
|
|
||||||
img = undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewSnapshot.prototype.perform = function ($event, snapshot, embedId, entryId, $scope, embed) {
|
|
||||||
var isOpen = false;
|
|
||||||
|
|
||||||
// onclick for menu items in overlay header context menu
|
|
||||||
$scope.menuPerform = function (menu) {
|
|
||||||
menu.perform();
|
|
||||||
closeOverlay();
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create the overlay element and add it to the document's body
|
|
||||||
$scope.cssClass = embed.cssClass;
|
|
||||||
$scope.embedType = embed.type;
|
|
||||||
$scope.entryName = embed.name;
|
|
||||||
$scope.snapDate = +embedId;
|
|
||||||
var element = this.$compile(headerTemplate)($scope);
|
|
||||||
|
|
||||||
var annotateAction = $scope.action.getActions({category: 'embed'})[1];
|
|
||||||
|
|
||||||
toggleOverlay = function () {
|
|
||||||
if (!isOpen) {
|
|
||||||
openOverlay(snapshot, element[0]);
|
|
||||||
isOpen = true;
|
|
||||||
} else {
|
|
||||||
closeOverlay();
|
|
||||||
isOpen = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
annotateImg = function () {
|
|
||||||
closeOverlay();
|
|
||||||
annotateAction.perform($event, snapshot, embedId, entryId, $scope);
|
|
||||||
};
|
|
||||||
|
|
||||||
toggleOverlay();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ViewSnapshot;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,50 +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 () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The notebook capability allows a domain object to know whether the
|
|
||||||
* notebook plugin is present or not.
|
|
||||||
*
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function NotebookCapability(typeService, domainObject) {
|
|
||||||
this.domainObject = domainObject;
|
|
||||||
this.typeService = typeService;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is a notebook domain Object.
|
|
||||||
*
|
|
||||||
* @returns {Boolean}
|
|
||||||
*/
|
|
||||||
NotebookCapability.prototype.isNotebook = function () {
|
|
||||||
return !!this.typeService.getType('notebook');
|
|
||||||
};
|
|
||||||
|
|
||||||
return NotebookCapability;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,367 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/*-- main controller file, here is the core functionality of the notebook plugin --*/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['zepto'],
|
|
||||||
function ($) {
|
|
||||||
|
|
||||||
|
|
||||||
function NotebookController(
|
|
||||||
$scope,
|
|
||||||
dialogService,
|
|
||||||
popupService,
|
|
||||||
agentService,
|
|
||||||
objectService,
|
|
||||||
navigationService,
|
|
||||||
now,
|
|
||||||
actionService,
|
|
||||||
$timeout,
|
|
||||||
$element,
|
|
||||||
$sce
|
|
||||||
) {
|
|
||||||
|
|
||||||
$scope.entriesEl = $(document.body).find('.t-entries-list');
|
|
||||||
$scope.sortEntries = $scope.domainObject.getModel().defaultSort;
|
|
||||||
$scope.showTime = "0";
|
|
||||||
$scope.editEntry = false;
|
|
||||||
$scope.entrySearch = '';
|
|
||||||
$scope.entryTypes = [];
|
|
||||||
$scope.embedActions = [];
|
|
||||||
$scope.currentEntryValue = '';
|
|
||||||
|
|
||||||
var SECONDS_IN_AN_HOUR = 60 * 60 * 1000;
|
|
||||||
|
|
||||||
this.scope = $scope;
|
|
||||||
|
|
||||||
$scope.hoursFilter = function (hours,entryTime) {
|
|
||||||
if (+hours) {
|
|
||||||
return entryTime > (Date.now() - SECONDS_IN_AN_HOUR * (+hours));
|
|
||||||
}else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.scrollToTop = function () {
|
|
||||||
var entriesContainer = $scope.entriesEl.parent();
|
|
||||||
entriesContainer[0].scrollTop = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.findEntryEl = function (entryId) {
|
|
||||||
var element = $($scope.entriesEl).find('#entry_' + entryId);
|
|
||||||
|
|
||||||
if (element[0]) {
|
|
||||||
return element.find("[contenteditable='true']");
|
|
||||||
} else {
|
|
||||||
var entries = $scope.entriesEl.children().children(),
|
|
||||||
lastOrFirst = $scope.sortEntries === "-createdOn" ? 0 : (entries.length - 1);
|
|
||||||
|
|
||||||
return $(entries[lastOrFirst]).find("[contenteditable='true']");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.findEntryPositionById = function (id) {
|
|
||||||
var foundId = -1;
|
|
||||||
|
|
||||||
$scope.domainObject.model.entries.forEach(function (element, index) {
|
|
||||||
if (element.id === id) {
|
|
||||||
foundId = index;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return foundId;
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.newEntry = function ($event) {
|
|
||||||
$scope.scrollToTop();
|
|
||||||
|
|
||||||
var entries = $scope.domainObject.model.entries,
|
|
||||||
lastEntry = entries[entries.length - 1],
|
|
||||||
id = Date.now();
|
|
||||||
|
|
||||||
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds) {
|
|
||||||
var createdEntry = {'id': id, 'createdOn': id};
|
|
||||||
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
model.entries.push(createdEntry);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
$scope.findEntryEl(lastEntry.id).focus();
|
|
||||||
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
model.entries[entries.length - 1].createdOn = id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
$scope.entrySearch = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$scope.deleteEntry = function ($event) {
|
|
||||||
var delId = +$event.currentTarget.id;
|
|
||||||
var errorDialog = dialogService.showBlockingMessage({
|
|
||||||
severity: "error",
|
|
||||||
title: "This action will permanently delete this Notebook entry. Do you want to continue?",
|
|
||||||
minimized: true, // want the notification to be minimized initially (don't show banner)
|
|
||||||
options: [{
|
|
||||||
label: "OK",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
var elementPos = $scope.findEntryPositionById(delId);
|
|
||||||
|
|
||||||
if (elementPos !== -1) {
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
model.entries.splice(elementPos, 1);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
window.console.log('delete error');
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
label: "Cancel",
|
|
||||||
callback: function () {
|
|
||||||
errorDialog.dismiss();
|
|
||||||
}
|
|
||||||
}]
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.textFocus = function ($event, entryId) {
|
|
||||||
if ($event.srcElement) {
|
|
||||||
$scope.currentEntryValue = $event.srcElement.innerText;
|
|
||||||
} else {
|
|
||||||
$event.target.innerText = '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//On text blur(when focus is removed)
|
|
||||||
$scope.textBlur = function ($event, entryId) {
|
|
||||||
// entryId is the unique numeric based on the original createdOn
|
|
||||||
if ($event.target) {
|
|
||||||
var elementPos = $scope.findEntryPositionById(+entryId);
|
|
||||||
|
|
||||||
// If the text of an entry has been changed, then update the text and the modifiedOn numeric
|
|
||||||
// Otherwise, don't do anything
|
|
||||||
if ($scope.currentEntryValue !== $event.target.innerText) {
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
model.entries[elementPos].text = $event.target.innerText;
|
|
||||||
model.entries[elementPos].modified = Date.now();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.finished = function (model) {
|
|
||||||
var lastEntry = model[model.length - 1];
|
|
||||||
|
|
||||||
if (!lastEntry.text) {
|
|
||||||
$scope.findEntryEl(lastEntry.id).focus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.handleActive = function () {
|
|
||||||
var newEntry = $scope.entriesEl.find('.active');
|
|
||||||
if (newEntry) {
|
|
||||||
newEntry.removeClass('active');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$scope.clearSearch = function () {
|
|
||||||
$scope.entrySearch = '';
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.viewSnapshot = function ($event,snapshot,embedId,entryId,$innerScope,domainObject) {
|
|
||||||
var viewAction = $scope.action.getActions({category: 'embed'})[0];
|
|
||||||
viewAction.perform($event, snapshot, embedId, entryId, $innerScope, domainObject);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.renderImage = function (img) {
|
|
||||||
return URL.createObjectURL(img);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.getDomainObj = function (id) {
|
|
||||||
return objectService.getObjects([id]);
|
|
||||||
};
|
|
||||||
|
|
||||||
function refreshComp(change) {
|
|
||||||
if (change && change.length) {
|
|
||||||
change[0].getCapability('action').getActions({key: 'remove'})[0].perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.actionToMenuOption = function (action) {
|
|
||||||
return {
|
|
||||||
key: action.getMetadata().key,
|
|
||||||
name: action.getMetadata().name,
|
|
||||||
cssClass: action.getMetadata().cssClass,
|
|
||||||
perform: action.perform
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
// Maintain all "conclude-editing" and "save" actions in the
|
|
||||||
// present context.
|
|
||||||
function updateActions() {
|
|
||||||
$scope.menuEmbed = $scope.action ?
|
|
||||||
$scope.action.getActions({category: 'embed'}) :
|
|
||||||
[];
|
|
||||||
|
|
||||||
$scope.menuEmbedNoSnap = $scope.action ?
|
|
||||||
$scope.action.getActions({category: 'embed-no-snap'}) :
|
|
||||||
[];
|
|
||||||
|
|
||||||
$scope.menuActions = $scope.action ?
|
|
||||||
$scope.action.getActions({key: 'window'}) :
|
|
||||||
[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update set of actions whenever the action capability
|
|
||||||
// changes or becomes available.
|
|
||||||
$scope.$watch("action", updateActions);
|
|
||||||
|
|
||||||
$scope.navigate = function ($event,embedType) {
|
|
||||||
if ($event) {
|
|
||||||
$event.preventDefault();
|
|
||||||
}
|
|
||||||
$scope.getDomainObj(embedType).then(function (resp) {
|
|
||||||
navigationService.setNavigation(resp[embedType]);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.saveSnap = function (url,embedPos,entryPos) {
|
|
||||||
var snapshot = false;
|
|
||||||
if (url) {
|
|
||||||
if (embedPos !== -1 && entryPos !== -1) {
|
|
||||||
var reader = new window.FileReader();
|
|
||||||
reader.readAsDataURL(url);
|
|
||||||
reader.onloadend = function () {
|
|
||||||
snapshot = reader.result;
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
if (model.entries[entryPos]) {
|
|
||||||
model.entries[entryPos].embeds[embedPos].snapshot = {
|
|
||||||
'src': snapshot,
|
|
||||||
'type': url.type,
|
|
||||||
'size': url.size,
|
|
||||||
'modified': Date.now()
|
|
||||||
};
|
|
||||||
model.entries[entryPos].embeds[embedPos].id = Date.now();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}else {
|
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
|
||||||
model.entries[entryPos].embeds[embedPos].snapshot = snapshot;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*---popups menu embeds----*/
|
|
||||||
|
|
||||||
function getEmbedActions(embedType) {
|
|
||||||
if (!$scope.embedActions.length) {
|
|
||||||
$scope.getDomainObj(embedType).then(function (resp) {
|
|
||||||
$scope.embedActions = [];
|
|
||||||
$scope.embedActions.push($scope.actionToMenuOption(
|
|
||||||
$scope.action.getActions({key: 'mct-preview-action', selectedObject: resp[embedType]})[0]
|
|
||||||
));
|
|
||||||
$scope.embedActions.push($scope.actionToMenuOption(
|
|
||||||
$scope.action.getActions({key: 'window', selectedObject: resp[embedType]})[0]
|
|
||||||
));
|
|
||||||
$scope.embedActions.push({
|
|
||||||
key: 'navigate',
|
|
||||||
name: 'Go to Original',
|
|
||||||
cssClass: '',
|
|
||||||
perform: function () {
|
|
||||||
$scope.navigate('', embedType);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$scope.openMenu = function ($event,embedType) {
|
|
||||||
$event.preventDefault();
|
|
||||||
|
|
||||||
getEmbedActions(embedType);
|
|
||||||
|
|
||||||
var body = $(document).find('body'),
|
|
||||||
initiatingEvent = agentService.isMobile() ?
|
|
||||||
'touchstart' : 'mousedown',
|
|
||||||
dismissExistingMenu,
|
|
||||||
menu;
|
|
||||||
|
|
||||||
var container = $($event.currentTarget).parent().parent();
|
|
||||||
|
|
||||||
menu = container.find('.menu-element');
|
|
||||||
|
|
||||||
// Remove the context menu
|
|
||||||
function dismiss() {
|
|
||||||
container.find('.hide-menu').append(menu);
|
|
||||||
body.off("mousedown", dismiss);
|
|
||||||
dismissExistingMenu = undefined;
|
|
||||||
$scope.embedActions = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dismiss any menu which was already showing
|
|
||||||
if (dismissExistingMenu) {
|
|
||||||
dismissExistingMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ...and record the presence of this menu.
|
|
||||||
dismissExistingMenu = dismiss;
|
|
||||||
|
|
||||||
popupService.display(menu, [$event.pageX,$event.pageY], {
|
|
||||||
marginX: 0,
|
|
||||||
marginY: -50
|
|
||||||
});
|
|
||||||
|
|
||||||
// Stop propagation so that clicks or touches on the menu do not close the menu
|
|
||||||
menu.on(initiatingEvent, function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
$timeout(dismiss, 300);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Dismiss the menu when body is clicked/touched elsewhere
|
|
||||||
// ('mousedown' because 'click' breaks left-click context menus)
|
|
||||||
// ('touchstart' because 'touch' breaks context menus up)
|
|
||||||
body.on(initiatingEvent, dismiss);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
$scope.$watchCollection("composition", refreshComp);
|
|
||||||
|
|
||||||
$scope.$watch('domainObject.getModel().defaultSort', function (newDefaultSort, oldDefaultSort) {
|
|
||||||
if (newDefaultSort !== oldDefaultSort) {
|
|
||||||
$scope.sortEntries = newDefaultSort;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$scope.$on('$destroy', function () {});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return NotebookController;
|
|
||||||
});
|
|
31
src/MCT.js
31
src/MCT.js
@ -35,8 +35,10 @@ define([
|
|||||||
'./ui/registries/InspectorViewRegistry',
|
'./ui/registries/InspectorViewRegistry',
|
||||||
'./ui/registries/ToolbarRegistry',
|
'./ui/registries/ToolbarRegistry',
|
||||||
'./ui/router/ApplicationRouter',
|
'./ui/router/ApplicationRouter',
|
||||||
|
'./ui/router/Browse',
|
||||||
'../platform/framework/src/Main',
|
'../platform/framework/src/Main',
|
||||||
'./styles-new/core.scss',
|
'./styles-new/core.scss',
|
||||||
|
'./styles-new/notebook.scss',
|
||||||
'./ui/components/layout/Layout.vue',
|
'./ui/components/layout/Layout.vue',
|
||||||
'vue'
|
'vue'
|
||||||
], function (
|
], function (
|
||||||
@ -54,8 +56,10 @@ define([
|
|||||||
InspectorViewRegistry,
|
InspectorViewRegistry,
|
||||||
ToolbarRegistry,
|
ToolbarRegistry,
|
||||||
ApplicationRouter,
|
ApplicationRouter,
|
||||||
|
Browse,
|
||||||
Main,
|
Main,
|
||||||
coreStyles,
|
coreStyles,
|
||||||
|
NotebookStyles,
|
||||||
Layout,
|
Layout,
|
||||||
Vue
|
Vue
|
||||||
) {
|
) {
|
||||||
@ -222,6 +226,7 @@ define([
|
|||||||
this.legacyRegistry = defaultRegistry;
|
this.legacyRegistry = defaultRegistry;
|
||||||
this.install(this.plugins.Plot());
|
this.install(this.plugins.Plot());
|
||||||
this.install(this.plugins.TelemetryTable());
|
this.install(this.plugins.TelemetryTable());
|
||||||
|
this.install(this.plugins.DisplayLayout());
|
||||||
|
|
||||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||||
@ -273,6 +278,7 @@ define([
|
|||||||
}.bind(this)
|
}.bind(this)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: remove with legacy types.
|
||||||
this.types.listKeys().forEach(function (typeKey) {
|
this.types.listKeys().forEach(function (typeKey) {
|
||||||
var type = this.types.get(typeKey);
|
var type = this.types.get(typeKey);
|
||||||
var legacyDefinition = type.toLegacyDefinition();
|
var legacyDefinition = type.toLegacyDefinition();
|
||||||
@ -280,26 +286,6 @@ define([
|
|||||||
this.legacyExtension('types', legacyDefinition);
|
this.legacyExtension('types', legacyDefinition);
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
// TODO: move this to adapter bundle.
|
|
||||||
this.legacyExtension('runs', {
|
|
||||||
depends: ['types[]'],
|
|
||||||
implementation: (types) => {
|
|
||||||
this.types.importLegacyTypes(types);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.objectViews.getAllProviders().forEach(function (p) {
|
|
||||||
this.legacyExtension('views', {
|
|
||||||
key: p.key,
|
|
||||||
provider: p,
|
|
||||||
name: p.name,
|
|
||||||
cssClass: p.cssClass,
|
|
||||||
description: p.description,
|
|
||||||
editable: p.editable,
|
|
||||||
template: '<mct-view mct-provider-key="' + p.key + '"/>'
|
|
||||||
});
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
legacyRegistry.register('adapter', this.legacyBundle);
|
legacyRegistry.register('adapter', this.legacyBundle);
|
||||||
legacyRegistry.enable('adapter');
|
legacyRegistry.enable('adapter');
|
||||||
|
|
||||||
@ -324,8 +310,6 @@ define([
|
|||||||
// something has depended upon objectService. Cool, right?
|
// something has depended upon objectService. Cool, right?
|
||||||
this.$injector.get('objectService');
|
this.$injector.get('objectService');
|
||||||
|
|
||||||
console.log('Rendering app layout.');
|
|
||||||
|
|
||||||
var appLayout = new Vue({
|
var appLayout = new Vue({
|
||||||
mixins: [Layout.default],
|
mixins: [Layout.default],
|
||||||
provide: {
|
provide: {
|
||||||
@ -334,7 +318,8 @@ define([
|
|||||||
});
|
});
|
||||||
domElement.appendChild(appLayout.$mount().$el);
|
domElement.appendChild(appLayout.$mount().$el);
|
||||||
|
|
||||||
|
this.layout = appLayout;
|
||||||
|
Browse(this);
|
||||||
this.router.start();
|
this.router.start();
|
||||||
this.emit('start');
|
this.emit('start');
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
@ -34,7 +34,9 @@ define([
|
|||||||
'./runs/TimeSettingsURLHandler',
|
'./runs/TimeSettingsURLHandler',
|
||||||
'./runs/TypeDeprecationChecker',
|
'./runs/TypeDeprecationChecker',
|
||||||
'./runs/LegacyTelemetryProvider',
|
'./runs/LegacyTelemetryProvider',
|
||||||
'./services/LegacyObjectAPIInterceptor'
|
'./runs/RegisterLegacyTypes',
|
||||||
|
'./services/LegacyObjectAPIInterceptor',
|
||||||
|
'./views/installLegacyViews'
|
||||||
], function (
|
], function (
|
||||||
legacyRegistry,
|
legacyRegistry,
|
||||||
ActionDialogDecorator,
|
ActionDialogDecorator,
|
||||||
@ -49,7 +51,9 @@ define([
|
|||||||
TimeSettingsURLHandler,
|
TimeSettingsURLHandler,
|
||||||
TypeDeprecationChecker,
|
TypeDeprecationChecker,
|
||||||
LegacyTelemetryProvider,
|
LegacyTelemetryProvider,
|
||||||
LegacyObjectAPIInterceptor
|
RegisterLegacyTypes,
|
||||||
|
LegacyObjectAPIInterceptor,
|
||||||
|
installLegacyViews
|
||||||
) {
|
) {
|
||||||
legacyRegistry.register('src/adapter', {
|
legacyRegistry.register('src/adapter', {
|
||||||
"extensions": {
|
"extensions": {
|
||||||
@ -149,6 +153,21 @@ define([
|
|||||||
"openmct",
|
"openmct",
|
||||||
"instantiate"
|
"instantiate"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
implementation: installLegacyViews,
|
||||||
|
depends: [
|
||||||
|
"openmct",
|
||||||
|
"views[]",
|
||||||
|
"instantiate"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
implementation: RegisterLegacyTypes,
|
||||||
|
depends: [
|
||||||
|
"types[]",
|
||||||
|
"openmct"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
licenses: [
|
licenses: [
|
||||||
|
17
src/adapter/runs/RegisterLegacyTypes.js
Normal file
17
src/adapter/runs/RegisterLegacyTypes.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
define([
|
||||||
|
|
||||||
|
], function (
|
||||||
|
|
||||||
|
) {
|
||||||
|
function RegisterLegacyTypes(types, openmct) {
|
||||||
|
types.forEach(function (legacyDefinition) {
|
||||||
|
if (!openmct.types.get(legacyDefinition.key)) {
|
||||||
|
console.warn(`DEPRECATION WARNING: Migrate type ${legacyDefinition.key} from ${legacyDefinition.bundle.path} to use the new Types API. Legacy type support will be removed soon.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.types.importLegacyTypes(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
return RegisterLegacyTypes;
|
||||||
|
});
|
93
src/adapter/views/LegacyViewProvider.js
Normal file
93
src/adapter/views/LegacyViewProvider.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
define([
|
||||||
|
|
||||||
|
], function (
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
function LegacyViewProvider(legacyView, openmct, convertToLegacyObject) {
|
||||||
|
console.warn(`DEPRECATION WARNING: Migrate ${legacyView.key} from ${legacyView.bundle.path} to use the new View APIs. Legacy view support will be removed soon.`);
|
||||||
|
return {
|
||||||
|
key: legacyView.key,
|
||||||
|
name: legacyView.name,
|
||||||
|
cssClass: legacyView.cssClass,
|
||||||
|
description: legacyView.description,
|
||||||
|
editable: legacyView.editable,
|
||||||
|
canView: function (domainObject) {
|
||||||
|
if (!domainObject || !domainObject.identifier) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (legacyView.type) {
|
||||||
|
return domainObject.type === legacyView.type;
|
||||||
|
}
|
||||||
|
let legacyObject = convertToLegacyObject(domainObject);
|
||||||
|
if (legacyView.needs) {
|
||||||
|
let meetsNeeds = legacyView.needs.every(k => legacyObject.hasCapability(k));
|
||||||
|
if (!meetsNeeds) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return openmct.$injector.get('policyService').allow(
|
||||||
|
'view', legacyView, legacyObject
|
||||||
|
);
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let $rootScope = openmct.$injector.get('$rootScope');
|
||||||
|
let templateLinker = openmct.$injector.get('templateLinker');
|
||||||
|
let scope = $rootScope.$new();
|
||||||
|
let legacyObject = convertToLegacyObject(domainObject);
|
||||||
|
let isDestroyed = false;
|
||||||
|
scope.domainObject = legacyObject;
|
||||||
|
scope.model = legacyObject.getModel();
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: function (container) {
|
||||||
|
// TODO: implement "gestures" support ?
|
||||||
|
let uses = legacyView.uses || [];
|
||||||
|
let promises = [];
|
||||||
|
let results = uses.map(function (capabilityKey, i) {
|
||||||
|
let result = legacyObject.useCapability(capabilityKey);
|
||||||
|
if (result.then) {
|
||||||
|
promises.push(result.then(function (r) {
|
||||||
|
results[i] = r;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
|
||||||
|
function link() {
|
||||||
|
if (isDestroyed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uses.forEach(function (key, i) {
|
||||||
|
scope[key] = results[i];
|
||||||
|
});
|
||||||
|
templateLinker.link(
|
||||||
|
scope,
|
||||||
|
openmct.$angular.element(container),
|
||||||
|
legacyView
|
||||||
|
);
|
||||||
|
container.style.height = '100%';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (promises.length) {
|
||||||
|
Promise.all(promises)
|
||||||
|
.then(function () {
|
||||||
|
link();
|
||||||
|
scope.$digest();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
link();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroy: function () {
|
||||||
|
scope.$destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return LegacyViewProvider;
|
||||||
|
|
||||||
|
});
|
22
src/adapter/views/installLegacyViews.js
Normal file
22
src/adapter/views/installLegacyViews.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
define([
|
||||||
|
'./LegacyViewProvider',
|
||||||
|
'../../api/objects/object-utils'
|
||||||
|
], function (
|
||||||
|
LegacyViewProvider,
|
||||||
|
objectUtils
|
||||||
|
) {
|
||||||
|
function installLegacyViews(openmct, legacyViews, instantiate) {
|
||||||
|
|
||||||
|
function convertToLegacyObject(domainObject) {
|
||||||
|
let keyString = objectUtils.makeKeyString(domainObject.identifier);
|
||||||
|
let oldModel = objectUtils.toOldFormat(domainObject);
|
||||||
|
return instantiate(oldModel, keyString);
|
||||||
|
}
|
||||||
|
|
||||||
|
legacyViews.forEach(function (legacyView) {
|
||||||
|
openmct.objectViews.addProvider(new LegacyViewProvider(legacyView, openmct, convertToLegacyObject));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return installLegacyViews;
|
||||||
|
});
|
@ -89,12 +89,13 @@ define(function () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Array.isArray(legacyDefinition.creatable) && 'creation' in legacyDefinition.creatable) {
|
|
||||||
|
if (legacyDefinition.features && legacyDefinition.features.includes("creation")) {
|
||||||
definition.creatable = true;
|
definition.creatable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return definition;
|
return definition;
|
||||||
}
|
};
|
||||||
|
|
||||||
return Type;
|
return Type;
|
||||||
});
|
});
|
||||||
|
@ -20,10 +20,9 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
import CSV from 'comma-separated-values';
|
||||||
'csv',
|
import {saveAs} from 'file-saver/FileSaver';
|
||||||
'saveAs'
|
|
||||||
], function (CSV, saveAs) {
|
|
||||||
class CSVExporter {
|
class CSVExporter {
|
||||||
export(rows, options) {
|
export(rows, options) {
|
||||||
let headers = (options && options.headers) ||
|
let headers = (options && options.headers) ||
|
||||||
@ -33,7 +32,6 @@ define([
|
|||||||
let blob = new Blob([csvText], { type: "text/csv" });
|
let blob = new Blob([csvText], { type: "text/csv" });
|
||||||
saveAs(blob, filename);
|
saveAs(blob, filename);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return CSVExporter;
|
export default CSVExporter;
|
||||||
});
|
|
||||||
|
206
src/plugins/displayLayout/DisplayLayout.vue
Normal file
206
src/plugins/displayLayout/DisplayLayout.vue
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
<template>
|
||||||
|
<div class="l-layout">
|
||||||
|
<div class="l-layout__object">
|
||||||
|
<!-- Background grid -->
|
||||||
|
<div class="l-layout__grid-holder c-grid" v-if="!drilledIn">
|
||||||
|
<div class="c-grid__x l-grid l-grid-x"
|
||||||
|
v-if="gridSize[0] >= 3"
|
||||||
|
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
|
||||||
|
</div>
|
||||||
|
<div class="c-grid__y l-grid l-grid-y"
|
||||||
|
v-if="gridSize[1] >= 3"
|
||||||
|
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<layout-frame v-for="item in frameItems"
|
||||||
|
class="l-layout__frame"
|
||||||
|
:key="item.id"
|
||||||
|
:item="item"
|
||||||
|
@drilledIn="updateDrilledInState"
|
||||||
|
@selected="updateSelectedState">
|
||||||
|
</layout-frame>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
.l-layout,
|
||||||
|
.c-grid,
|
||||||
|
.c-grid__x,
|
||||||
|
.c-grid__y {
|
||||||
|
@include abs();
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-layout {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
&__grid-holder {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__object {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__frame {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-grid {
|
||||||
|
z-index: -1;
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
&__x { @include bgTicks($colorGridLines, 'x'); }
|
||||||
|
&__y { @include bgTicks($colorGridLines, 'y'); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-editing {
|
||||||
|
.l-layout {
|
||||||
|
background: rgba($colorKey, 0.1);
|
||||||
|
|
||||||
|
&.s-selected,
|
||||||
|
&.s-selected-parent {
|
||||||
|
[class*="__grid-holder"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import LayoutFrame from './LayoutFrame.vue';
|
||||||
|
|
||||||
|
const DEFAULT_GRID_SIZE = [32, 32],
|
||||||
|
DEFAULT_DIMENSIONS = [12, 8],
|
||||||
|
MINIMUM_FRAME_SIZE = [320, 180];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
gridSize: DEFAULT_GRID_SIZE,
|
||||||
|
frameItems: [],
|
||||||
|
frames: [],
|
||||||
|
composition: Object,
|
||||||
|
frameStyles: [],
|
||||||
|
rawPositions: {},
|
||||||
|
isEditing: true,
|
||||||
|
initSelect: true,
|
||||||
|
drilledIn: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
inject: ['openmct'],
|
||||||
|
props: ['domainObject'],
|
||||||
|
components: {
|
||||||
|
LayoutFrame
|
||||||
|
},
|
||||||
|
created: function () {
|
||||||
|
console.log("domainObject", JSON.parse(JSON.stringify(this.domainObject)));
|
||||||
|
|
||||||
|
this.populatePositions(this.domainObject.configuration.layout.panels);
|
||||||
|
|
||||||
|
this.composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
this.composition.on('add', this.onAddComposition);
|
||||||
|
this.composition.on('remove', this.onRemoveComposition);
|
||||||
|
this.composition.load();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onAddComposition(domainObject) {
|
||||||
|
console.log('composition object', domainObject);
|
||||||
|
const id = this.openmct.objects.makeKeyString(domainObject.identifier)
|
||||||
|
this.frameItems.push({
|
||||||
|
id: id,
|
||||||
|
hasFrame: this.hasFrame(id),
|
||||||
|
domainObject,
|
||||||
|
style: this.frameStyles[id],
|
||||||
|
drilledIn: this.isDrilledIn(id),
|
||||||
|
selected: false
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onRemoveComposition(identifier) {
|
||||||
|
// TODO: remove the object from frameItems
|
||||||
|
},
|
||||||
|
populatePositions(panels) {
|
||||||
|
Object.keys(panels).forEach(function (key, index) {
|
||||||
|
this.rawPositions[key] = {
|
||||||
|
position: panels[key].position || this.defaultPosition(index),
|
||||||
|
dimensions: panels[key].dimensions || this.defaultDimensions()
|
||||||
|
};
|
||||||
|
this.frameStyles[key] = this.convertPosition(this.rawPositions[key]);
|
||||||
|
this.frames[key] = panels[key].hasFrame;
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
defaultPosition(index) {
|
||||||
|
return [index, index];
|
||||||
|
},
|
||||||
|
defaultDimensions() {
|
||||||
|
let gridSize = this.gridSize;
|
||||||
|
return MINIMUM_FRAME_SIZE.map(function (min, i) {
|
||||||
|
return Math.max(
|
||||||
|
Math.ceil(min / gridSize[i]),
|
||||||
|
DEFAULT_DIMENSIONS[i]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
convertPosition(raw) {
|
||||||
|
return {
|
||||||
|
left: (this.gridSize[0] * raw.position[0]) + 'px',
|
||||||
|
top: (this.gridSize[1] * raw.position[1]) + 'px',
|
||||||
|
width: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
||||||
|
height: (this.gridSize[1] * raw.dimensions[1]) + 'px',
|
||||||
|
minWidth: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
||||||
|
minHeight: (this.gridSize[1] * raw.dimensions[1]) + 'px'
|
||||||
|
};
|
||||||
|
},
|
||||||
|
hasFrame(id) {
|
||||||
|
return this.frames[id]
|
||||||
|
},
|
||||||
|
setSelection(selection) {
|
||||||
|
if (selection.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateDrilledInState();
|
||||||
|
this.updateSelectedState();
|
||||||
|
},
|
||||||
|
updateDrilledInState(id) {
|
||||||
|
this.drilledIn = id;
|
||||||
|
this.frameItems.forEach(function (item) {
|
||||||
|
item.drilledIn = item.id === id;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateSelectedState(id) {
|
||||||
|
this.frameItems.forEach(function (item) {
|
||||||
|
item.selected = item.id === id;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
isDrilledIn(id) {
|
||||||
|
return this.drilledIn === id;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
|
this.$el,
|
||||||
|
{
|
||||||
|
item: this.domainObject
|
||||||
|
},
|
||||||
|
this.initSelect
|
||||||
|
);
|
||||||
|
|
||||||
|
this.openmct.selection.on('change', this.setSelection);
|
||||||
|
},
|
||||||
|
destroyed: function () {
|
||||||
|
this.composition.off('add', this.onAddComposition);
|
||||||
|
this.composition.off('remove', this.onRemoveComposition);
|
||||||
|
this.openmct.off('change', this.selection);
|
||||||
|
this.removeSelectable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
251
src/plugins/displayLayout/LayoutFrame.vue
Normal file
251
src/plugins/displayLayout/LayoutFrame.vue
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
<template>
|
||||||
|
<!-- - TODO: styles for selectable, moveable, etc. -->
|
||||||
|
<div class="c-frame has-local-controls"
|
||||||
|
:style="item.style"
|
||||||
|
:class="classObject"
|
||||||
|
@dblclick="drill(item.id, $event)">
|
||||||
|
<div class="c-frame__header">
|
||||||
|
<div class="c-frame__header__start">
|
||||||
|
<div class="c-frame__name icon-object">Header</div>
|
||||||
|
<div class="c-frame__context-actions c-disclosure-button"></div>
|
||||||
|
</div>
|
||||||
|
<div class="c-frame__header__end">
|
||||||
|
<div class="c-button icon-expand local-controls--hidden"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<object-view
|
||||||
|
class="c-frame__object-view"
|
||||||
|
:object="item.domainObject"></object-view>
|
||||||
|
|
||||||
|
<!-- Drag handles -->
|
||||||
|
<div class="c-frame-edit">
|
||||||
|
<div class="c-frame-edit__move"></div>
|
||||||
|
<div class="c-frame-edit__handle --nw"></div>
|
||||||
|
<div class="c-frame-edit__handle --ne"></div>
|
||||||
|
<div class="c-frame-edit__handle --se"></div>
|
||||||
|
<div class="c-frame-edit__handle --sw"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
/******************************* FRAME */
|
||||||
|
.c-frame {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
/*************************** HEADER */
|
||||||
|
&__header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-bottom: $interiorMargin;
|
||||||
|
|
||||||
|
> [class*="__"] {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="__start"] {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="__end"] {
|
||||||
|
justify-content: flex-end;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
[class*="button"] {
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
@include ellipsize();
|
||||||
|
flex: 0 1 auto;
|
||||||
|
font-size: 1.2em;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Object type icon
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** OBJECT VIEW */
|
||||||
|
&__object-view {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** NO-FRAME */
|
||||||
|
&.no-frame {
|
||||||
|
[class*="__header"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.no-frame) {
|
||||||
|
background: $colorBodyBg;
|
||||||
|
border: 1px solid $colorInteriorBorder;
|
||||||
|
padding: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** SELECTION */
|
||||||
|
&.s-selected {
|
||||||
|
//Legacy name for now
|
||||||
|
border-color: $colorKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-drilled-in {
|
||||||
|
border: 1px dashed deeppink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*************************** EDITING */
|
||||||
|
.is-editing .c-frame:not(.is-drilled-in) {
|
||||||
|
border: 1px dotted rgba($colorKey, 0.5);
|
||||||
|
|
||||||
|
&.s-selected {
|
||||||
|
> .c-frame-edit {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-frame-edit {
|
||||||
|
$z: 10;
|
||||||
|
|
||||||
|
@include abs();
|
||||||
|
box-shadow: rgba($colorKey, 1) 0 0 10px;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&__move {
|
||||||
|
@include abs();
|
||||||
|
cursor: move;
|
||||||
|
z-index: $z;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__handle {
|
||||||
|
$d: 8px;
|
||||||
|
$o: floor($d * -0.5);
|
||||||
|
background: rgba($colorKey, 0.3);
|
||||||
|
border: 1px solid $colorKey;
|
||||||
|
position: absolute;
|
||||||
|
width: $d; height: $d;
|
||||||
|
top: auto; right: auto; bottom: auto; left: auto;
|
||||||
|
z-index: $z + 1;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Extended hit area
|
||||||
|
$m: -5px;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: $m; right: $m; bottom: $m; left: $m;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $colorKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.--nw {
|
||||||
|
cursor: nw-resize;
|
||||||
|
left: $o; top: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.--ne {
|
||||||
|
cursor: ne-resize;
|
||||||
|
right: $o; top: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.--se {
|
||||||
|
cursor: se-resize;
|
||||||
|
right: $o; bottom: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.--sw {
|
||||||
|
cursor: sw-resize;
|
||||||
|
left: $o; bottom: $o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import ObjectView from '../../ui/components/layout/ObjectView.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
props: {
|
||||||
|
item: Object
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
ObjectView
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
classObject: function () {
|
||||||
|
return {
|
||||||
|
'is-drilled-in': this.item.drilledIn,
|
||||||
|
'no-frame': !this.item.hasFrame
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setSelection(selection) {
|
||||||
|
if (selection.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = this.openmct.objects.makeKeyString(selection[0].context.item.identifier);
|
||||||
|
if (this.item.id === id) {
|
||||||
|
this.$emit('selected', id);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drill(id, $event) {
|
||||||
|
if ($event) {
|
||||||
|
$event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.isBeingEdited(this.item.domainObject)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.openmct.composition.get(this.item.domainObject) === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable for fixed position.
|
||||||
|
if (this.item.domainObject.type === 'telemetry.fixed') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('drilledIn', id);
|
||||||
|
},
|
||||||
|
isBeingEdited(object) {
|
||||||
|
// TODO: add logic when inEditContext() is implemented in Vue.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
|
this.$el,
|
||||||
|
{
|
||||||
|
item: this.item.domainObject
|
||||||
|
},
|
||||||
|
this.item.selected
|
||||||
|
);
|
||||||
|
|
||||||
|
this.openmct.selection.on('change', this.setSelection);
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.openmct.off('change', this.selection);
|
||||||
|
this.removeSelectable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
45
src/plugins/displayLayout/plugin.js
Normal file
45
src/plugins/displayLayout/plugin.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import Layout from './DisplayLayout.vue'
|
||||||
|
import Vue from 'vue'
|
||||||
|
import objectUtils from '../../api/objects/object-utils.js'
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
return function (openmct) {
|
||||||
|
console.log("Installing Layout component...");
|
||||||
|
|
||||||
|
openmct.objectViews.addProvider({
|
||||||
|
key: 'layout.view',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'layout';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let component;
|
||||||
|
return {
|
||||||
|
show(container) {
|
||||||
|
component = new Vue({
|
||||||
|
components: {
|
||||||
|
Layout
|
||||||
|
},
|
||||||
|
template: '<layout :domain-object="domainObject"></layout>',
|
||||||
|
provide: {
|
||||||
|
openmct,
|
||||||
|
objectUtils
|
||||||
|
},
|
||||||
|
el: container,
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
domainObject: domainObject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy() {
|
||||||
|
component.$destroy();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
215
src/plugins/notebook/plugin.js
Normal file
215
src/plugins/notebook/plugin.js
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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([
|
||||||
|
"./src/controllers/NotebookController",
|
||||||
|
"./src/controllers/NewEntryController",
|
||||||
|
"./src/controllers/SelectSnapshotController",
|
||||||
|
"./src/actions/NewEntryContextual",
|
||||||
|
"./src/actions/AnnotateSnapshot",
|
||||||
|
"./src/directives/MCTSnapshot",
|
||||||
|
"./src/directives/EntryDnd",
|
||||||
|
"./res/templates/controls/snapSelect.html",
|
||||||
|
"./res/templates/controls/embedControl.html",
|
||||||
|
"./res/templates/annotation.html",
|
||||||
|
"./res/templates/draggedEntry.html"
|
||||||
|
], function (
|
||||||
|
NotebookController,
|
||||||
|
NewEntryController,
|
||||||
|
SelectSnapshotController,
|
||||||
|
newEntryAction,
|
||||||
|
AnnotateSnapshotAction,
|
||||||
|
MCTSnapshotDirective,
|
||||||
|
EntryDndDirective,
|
||||||
|
snapSelectTemplate,
|
||||||
|
embedControlTemplate,
|
||||||
|
annotationTemplate,
|
||||||
|
draggedEntryTemplate
|
||||||
|
) {
|
||||||
|
var installed = false;
|
||||||
|
|
||||||
|
function NotebookPlugin() {
|
||||||
|
return function install(openmct) {
|
||||||
|
if (installed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
installed = true;
|
||||||
|
|
||||||
|
openmct.legacyRegistry.register('notebook', {
|
||||||
|
name: 'Notebook Plugin',
|
||||||
|
extensions: {
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
key: 'notebook',
|
||||||
|
name: 'Notebook',
|
||||||
|
cssClass: 'icon-notebook',
|
||||||
|
description: 'Create and save timestamped notes with embedded object snapshots.',
|
||||||
|
features: 'creation',
|
||||||
|
model: {
|
||||||
|
entries: [],
|
||||||
|
composition: [],
|
||||||
|
entryTypes: [],
|
||||||
|
defaultSort: '-createdOn'
|
||||||
|
},
|
||||||
|
properties: [
|
||||||
|
{
|
||||||
|
key: 'defaultSort',
|
||||||
|
name: 'Default Sort',
|
||||||
|
control: 'select',
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Newest First',
|
||||||
|
value: "-createdOn",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Oldest First',
|
||||||
|
value: "createdOn"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
cssClass: 'l-inline'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
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"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mctEntryDnd",
|
||||||
|
"implementation": EntryDndDirective,
|
||||||
|
"depends": [
|
||||||
|
"$rootScope",
|
||||||
|
"$compile",
|
||||||
|
"dndService",
|
||||||
|
"typeService",
|
||||||
|
"notificationService"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
representations: [
|
||||||
|
{
|
||||||
|
"key": "draggedEntry",
|
||||||
|
"template": draggedEntryTemplate
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.legacyRegistry.enable('notebook');
|
||||||
|
|
||||||
|
openmct.objectViews.addProvider({
|
||||||
|
key: 'notebook-vue',
|
||||||
|
name: 'Notebook View',
|
||||||
|
cssClass: 'icon-notebook',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'notebook';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
var controller = new NotebookController (openmct, domainObject);
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: controller.show,
|
||||||
|
destroy: controller.destroy
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return NotebookPlugin;
|
||||||
|
});
|
@ -25,6 +25,5 @@
|
|||||||
ng-options="opt.value as opt.name for opt in options"
|
ng-options="opt.value as opt.name for opt in options"
|
||||||
ng-required="ngRequired"
|
ng-required="ngRequired"
|
||||||
name="mctControl">
|
name="mctControl">
|
||||||
<!-- <option value="" ng-show="!ngModel[field]">- Select One -</option> -->
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
32
src/plugins/notebook/res/templates/embed.html
Normal file
32
src/plugins/notebook/res/templates/embed.html
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<div class="c-ne__embed">
|
||||||
|
<div class="c-ne__embed__snap-thumb"
|
||||||
|
v-if="embed.snapshot"
|
||||||
|
v-on:click="openSnapshot">
|
||||||
|
<img v-bind:src="embed.snapshot.src">
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embed__info">
|
||||||
|
<div class="c-ne__embed__name">
|
||||||
|
<a class="c-ne__embed__link"
|
||||||
|
v-on:click="navigate(embed.type)"
|
||||||
|
v-bind:class="[embed.cssClass]">{{embed.name}}</a>
|
||||||
|
<a class="c-ne__embed__context-available icon-arrow-down"
|
||||||
|
v-on:click="toggleActionMenu"></a>
|
||||||
|
</div>
|
||||||
|
<div class="hide-menu hidden">
|
||||||
|
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
||||||
|
<div class="menu context-menu">
|
||||||
|
<ul>
|
||||||
|
<li v-for="action in actions"
|
||||||
|
v-bind:class="[action.cssClass]"
|
||||||
|
v-on:click="action.perform(embed, entry)">
|
||||||
|
{{ action.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embed__time" v-if="embed.snapshot">
|
||||||
|
{{formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
35
src/plugins/notebook/res/templates/entry.html
Normal file
35
src/plugins/notebook/res/templates/entry.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<li class="c-notebook__entry c-ne has-local-controls"
|
||||||
|
v-on:drop="dropOnEntry(entry.id)"
|
||||||
|
v-on:dragover="dragoverOnEntry"
|
||||||
|
>
|
||||||
|
<div class="c-ne__time-and-content">
|
||||||
|
<div class="c-ne__time">
|
||||||
|
<span>{{formatTime(entry.createdOn, 'YYYY-MM-DD')}}</span>
|
||||||
|
<span>{{formatTime(entry.createdOn, 'HH:mm:ss')}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__content">
|
||||||
|
<!-- TODO: fix styling for c-input-inline when SCSS is merged and remove s-input-inline class here -->
|
||||||
|
<div class="c-ne__text c-input-inline s-input-inline"
|
||||||
|
contenteditable="true"
|
||||||
|
ref="contenteditable"
|
||||||
|
v-on:blur="textBlur($event, entry.id)"
|
||||||
|
v-on:focus="textFocus($event, entry.id)"
|
||||||
|
v-bind:key="entry.id"
|
||||||
|
v-html="entry.text">
|
||||||
|
</div>
|
||||||
|
<div class="c-ne__embeds">
|
||||||
|
<notebook-embed
|
||||||
|
v-for="(embed, index) in entry.embeds"
|
||||||
|
v-bind:embed="embed"
|
||||||
|
v-bind:entry="entry"
|
||||||
|
></notebook-embed>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-ne__local-controls--hidden">
|
||||||
|
<a class="c-click-icon icon-trash"
|
||||||
|
title="Delete this entry"
|
||||||
|
v-on:click="deleteEntry"></a>
|
||||||
|
</div>
|
||||||
|
</li>
|
37
src/plugins/notebook/res/templates/notebook.html
Normal file
37
src/plugins/notebook/res/templates/notebook.html
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<div class="c-notebook">
|
||||||
|
<div class="c-notebook__head">
|
||||||
|
<search class="c-notebook__search"
|
||||||
|
v-model="entrySearch"
|
||||||
|
v-on:input="search($event)"
|
||||||
|
v-on:clear="entrySearch = ''; search($event)"></search>
|
||||||
|
<div class="c-notebook__controls">
|
||||||
|
<div class="select c-notebook__controls__time">
|
||||||
|
<select v-model="showTime">
|
||||||
|
<option value="0" selected="selected">Show all</option>
|
||||||
|
<option value="1">Last hour</option>
|
||||||
|
<option value="8">Last 8 hours</option>
|
||||||
|
<option value="24">Last 24 hours</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="select c-notebook__controls__sort">
|
||||||
|
<select v-model="sortEntries">
|
||||||
|
<option value="-createdOn" selected="selected">Newest first</option>
|
||||||
|
<option value="createdOn">Oldest first</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-notebook__drag-area icon-plus"
|
||||||
|
v-on:click="newEntry($event)"
|
||||||
|
id="newEntry" mct-entry-dnd>
|
||||||
|
<span class="c-notebook__drag-area__label">To start a new entry, click here or drag and drop any object</span>
|
||||||
|
</div>
|
||||||
|
<div class="c-notebook__entries" ng-mouseover="handleActive()">
|
||||||
|
<ul>
|
||||||
|
<notebook-entry
|
||||||
|
v-for="entry in filterBySearch(entries, entrySearch)"
|
||||||
|
v-bind:entry="entry"
|
||||||
|
></notebook-entry>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
50
src/plugins/notebook/res/templates/viewSnapshot.html
Normal file
50
src/plugins/notebook/res/templates/viewSnapshot.html
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<div class="abs overlay l-large-view">
|
||||||
|
<div class="abs blocker" v-on:click="close"></div>
|
||||||
|
|
||||||
|
<div class="abs outer-holder">
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="close icon-x-in-circle"
|
||||||
|
v-on:click="close">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="abs inner-holder l-flex-col">
|
||||||
|
<div class="t-contents flex-elem holder grows">
|
||||||
|
|
||||||
|
<div class="t-snapshot abs l-view-header">
|
||||||
|
<div class="abs object-browse-bar l-flex-row">
|
||||||
|
<div class="left flex-elem l-flex-row grows">
|
||||||
|
<div class="object-header flex-elem l-flex-row grows">
|
||||||
|
<div class="type-icon flex-elem embed-icon holder" v-bind:class="embed.cssClass"></div>
|
||||||
|
<div class="title-label flex-elem holder flex-can-shrink">{{embed.name}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||||
|
<div class="flex-elem holder flex-can-shrink s-snapshot-datetime">
|
||||||
|
SNAPSHOT {{formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss')}}
|
||||||
|
</div>
|
||||||
|
<a class="s-button icon-pencil" title="Annotate">
|
||||||
|
<span class="title-label">Annotate</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="abs object-holder t-image-holder s-image-holder">
|
||||||
|
<div
|
||||||
|
class="image-main s-image-main"
|
||||||
|
v-bind:style="{ backgroundImage: 'url(' + embed.snapshot.src + ')' }">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="bottom-bar flex-elem holder"
|
||||||
|
v-on:click="close">
|
||||||
|
|
||||||
|
<a class="t-done s-button major">Done</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -26,6 +26,7 @@
|
|||||||
define(
|
define(
|
||||||
["painterro", "zepto"],
|
["painterro", "zepto"],
|
||||||
function (Painterro, $) {
|
function (Painterro, $) {
|
||||||
|
|
||||||
var annotationStruct = {
|
var annotationStruct = {
|
||||||
title: "Annotate Snapshot",
|
title: "Annotate Snapshot",
|
||||||
template: "annotate-snapshot",
|
template: "annotate-snapshot",
|
||||||
@ -107,9 +108,6 @@ define(
|
|||||||
done(true);
|
done(true);
|
||||||
}
|
}
|
||||||
}).show(snapshot);
|
}).show(snapshot);
|
||||||
|
|
||||||
$(document.body).find('.ptro-icon-btn').addClass('s-button');
|
|
||||||
$(document.body).find('.ptro-input').addClass('s-button');
|
|
||||||
});
|
});
|
||||||
}];
|
}];
|
||||||
|
|
@ -90,7 +90,7 @@ define(
|
|||||||
var dialogService = this.dialogService;
|
var dialogService = this.dialogService;
|
||||||
var rootScope = this.$rootScope;
|
var rootScope = this.$rootScope;
|
||||||
rootScope.newEntryText = '';
|
rootScope.newEntryText = '';
|
||||||
// Create the overlay element and add it to the document's body
|
// // Create the overlay element and add it to the document's body
|
||||||
this.$rootScope.selObj = domainObj;
|
this.$rootScope.selObj = domainObj;
|
||||||
this.$rootScope.selValue = "";
|
this.$rootScope.selValue = "";
|
||||||
var newScope = rootScope.$new();
|
var newScope = rootScope.$new();
|
||||||
@ -187,7 +187,7 @@ define(
|
|||||||
var domainObject = context.domainObject;
|
var domainObject = context.domainObject;
|
||||||
|
|
||||||
if (domainObject) {
|
if (domainObject) {
|
||||||
if (domainObject.getModel().type === 'Notebook') {
|
if (domainObject.getModel().type === 'notebook') {
|
||||||
// do not allow in context of a notebook
|
// do not allow in context of a notebook
|
||||||
return false;
|
return false;
|
||||||
} else if (domainObject.getModel().type.includes('imagery')) {
|
} else if (domainObject.getModel().type.includes('imagery')) {
|
130
src/plugins/notebook/src/actions/snapshotAction.js
Normal file
130
src/plugins/notebook/src/actions/snapshotAction.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
|
);
|
198
src/plugins/notebook/src/controllers/EmbedController.js
Normal file
198
src/plugins/notebook/src/controllers/EmbedController.js
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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([
|
||||||
|
'moment',
|
||||||
|
'zepto',
|
||||||
|
'../utils/SnapshotOverlay',
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
Moment,
|
||||||
|
$,
|
||||||
|
SnapshotOverlay
|
||||||
|
) {
|
||||||
|
function EmbedController (openmct, domainObject) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
this.domainObject = domainObject;
|
||||||
|
this.objectService = openmct.$injector.get('objectService');
|
||||||
|
this.navigationService = openmct.$injector.get('navigationService');
|
||||||
|
this.popupService = openmct.$injector.get('popupService');
|
||||||
|
this.agentService = openmct.$injector.get('agentService');
|
||||||
|
this.dialogService = openmct.$injector.get('dialogService');
|
||||||
|
|
||||||
|
|
||||||
|
this.navigate = this.navigate.bind(this);
|
||||||
|
this.exposedData = this.exposedData.bind(this);
|
||||||
|
this.exposedMethods = this.exposedMethods.bind(this);
|
||||||
|
this.toggleActionMenu = this.toggleActionMenu.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedController.prototype.navigate = function (embedType) {
|
||||||
|
this.objectService.getObjects([embedType]).then(function (objects) {
|
||||||
|
this.navigationService.setNavigation(objects[embedType]);
|
||||||
|
}.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.openSnapshot = function () {
|
||||||
|
if (!this.snapshotOverlay) {
|
||||||
|
this.snapShotOverlay = new SnapshotOverlay(this.embed, this.formatTime);
|
||||||
|
} else {
|
||||||
|
this.snapShotOverlay = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.formatTime = function (unixTime, timeFormat) {
|
||||||
|
return Moment(unixTime).format(timeFormat);
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.findInArray = function (array, id) {
|
||||||
|
var foundId = -1;
|
||||||
|
|
||||||
|
array.forEach(function (element, index) {
|
||||||
|
if (element.id === id) {
|
||||||
|
foundId = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return foundId;
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.actionToMenuDecorator = function (action) {
|
||||||
|
return {
|
||||||
|
name: action.getMetadata().name,
|
||||||
|
cssClass: action.getMetadata().cssClass,
|
||||||
|
perform: action.perform
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.populateActionMenu = function (objectService, actionService) {
|
||||||
|
return function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
objectService.getObjects([self.embed.type]).then(function (resp) {
|
||||||
|
var domainObject = resp[self.embed.type],
|
||||||
|
previewAction = actionService.getActions({key: 'mct-preview-action', domainObject: domainObject})[0];
|
||||||
|
|
||||||
|
self.actions.push(self.actionToMenuDecorator(previewAction));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.removeEmbedAction = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
return {
|
||||||
|
name: 'Remove Embed',
|
||||||
|
cssClass: 'icon-trash',
|
||||||
|
perform: function (embed, entry) {
|
||||||
|
var entryPosition = self.findInArray(self.domainObject.entries, entry.id),
|
||||||
|
embedPosition = self.findInArray(entry.embeds, embed.id);
|
||||||
|
|
||||||
|
var warningDialog = self.dialogService.showBlockingMessage({
|
||||||
|
severity: "error",
|
||||||
|
title: "This action will permanently delete this embed. Do you wish to continue?",
|
||||||
|
options: [{
|
||||||
|
label: "OK",
|
||||||
|
callback: function () {
|
||||||
|
entry.embeds.splice(embedPosition, 1);
|
||||||
|
var dirString = 'entries[' + entryPosition + '].embeds';
|
||||||
|
|
||||||
|
self.openmct.objects.mutate(self.domainObject, dirString, entry.embeds);
|
||||||
|
|
||||||
|
warningDialog.dismiss();
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
label: "Cancel",
|
||||||
|
callback: function () {
|
||||||
|
warningDialog.dismiss();
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.toggleActionMenu = function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
var body = $(document.body),
|
||||||
|
container = $(event.target.parentElement.parentElement),
|
||||||
|
initiatingEvent = this.agentService.isMobile() ?
|
||||||
|
'touchstart' : 'mousedown',
|
||||||
|
menu = container.find('.menu-element'),
|
||||||
|
dismissExistingMenu;
|
||||||
|
|
||||||
|
// Remove the context menu
|
||||||
|
function dismiss() {
|
||||||
|
container.find('.hide-menu').append(menu);
|
||||||
|
body.off(initiatingEvent, dismiss);
|
||||||
|
menu.off(initiatingEvent, menuClickHandler);
|
||||||
|
dismissExistingMenu = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function menuClickHandler(e) {
|
||||||
|
e.stopPropagation();
|
||||||
|
window.setTimeout(dismiss, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dismiss any menu which was already showing
|
||||||
|
if (dismissExistingMenu) {
|
||||||
|
dismissExistingMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and record the presence of this menu.
|
||||||
|
dismissExistingMenu = dismiss;
|
||||||
|
|
||||||
|
this.popupService.display(menu, [event.pageX,event.pageY], {
|
||||||
|
marginX: 0,
|
||||||
|
marginY: -50
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stop propagation so that clicks or touches on the menu do not close the menu
|
||||||
|
menu.on(initiatingEvent, menuClickHandler);
|
||||||
|
|
||||||
|
body.on(initiatingEvent, dismiss);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.exposedData = function () {
|
||||||
|
return {
|
||||||
|
actions: [this.removeEmbedAction()],
|
||||||
|
showActionMenu: false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedController.prototype.exposedMethods = function () {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
return {
|
||||||
|
navigate: self.navigate,
|
||||||
|
openSnapshot: self.openSnapshot,
|
||||||
|
formatTime: self.formatTime,
|
||||||
|
toggleActionMenu: self.toggleActionMenu,
|
||||||
|
actionToMenuDecorator: self.actionToMenuDecorator
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
return EmbedController;
|
||||||
|
});
|
150
src/plugins/notebook/src/controllers/EntryController.js
Normal file
150
src/plugins/notebook/src/controllers/EntryController.js
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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([
|
||||||
|
'moment'
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
Moment
|
||||||
|
) {
|
||||||
|
|
||||||
|
function EntryController (openmct, domainObject) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
this.domainObject = domainObject;
|
||||||
|
this.dndService = this.openmct.$injector.get('dndService');
|
||||||
|
this.dialogService = this.openmct.$injector.get('dialogService');
|
||||||
|
|
||||||
|
this.currentEntryValue = '';
|
||||||
|
|
||||||
|
this.exposedMethods = this.exposedMethods.bind(this);
|
||||||
|
this.exposedData = this.exposedData.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
EntryController.prototype.entryPosById = function (entryId) {
|
||||||
|
var foundId = -1;
|
||||||
|
|
||||||
|
this.domainObject.entries.forEach(function (element, index) {
|
||||||
|
if (element.id === entryId) {
|
||||||
|
foundId = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return foundId;
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.textFocus = function ($event) {
|
||||||
|
if ($event.target) {
|
||||||
|
this.currentEntryValue = $event.target.innerText;
|
||||||
|
} else {
|
||||||
|
$event.target.innerText = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.textBlur = function ($event, entryId) {
|
||||||
|
if ($event.target) {
|
||||||
|
var entryPos = this.entryPosById(entryId);
|
||||||
|
|
||||||
|
if (this.currentEntryValue !== $event.target.innerText) {
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries[' + entryPos + '].text', $event.target.innerText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.formatTime = function (unixTime, timeFormat) {
|
||||||
|
return Moment(unixTime).format(timeFormat);
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.deleteEntry = function () {
|
||||||
|
var entryPos = this.entryPosById(this.entry.id),
|
||||||
|
domainObject = this.domainObject,
|
||||||
|
openmct = this.openmct;
|
||||||
|
|
||||||
|
if (entryPos !== -1) {
|
||||||
|
|
||||||
|
var errorDialog = this.dialogService.showBlockingMessage({
|
||||||
|
severity: "error",
|
||||||
|
title: "This action will permanently delete this Notebook entry. Do you wish to continue?",
|
||||||
|
options: [{
|
||||||
|
label: "OK",
|
||||||
|
callback: function () {
|
||||||
|
domainObject.entries.splice(entryPos, 1);
|
||||||
|
openmct.objects.mutate(domainObject, 'entries', domainObject.entries);
|
||||||
|
|
||||||
|
errorDialog.dismiss();
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
label: "Cancel",
|
||||||
|
callback: function () {
|
||||||
|
errorDialog.dismiss();
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.dropOnEntry = function (entryId) {
|
||||||
|
var selectedObject = this.dndService.getData('mct-domain-object'),
|
||||||
|
selectedObjectId = selectedObject.getId(),
|
||||||
|
selectedModel = selectedObject.getModel(),
|
||||||
|
cssClass = selectedObject.getCapability('type').typeDef.cssClass,
|
||||||
|
entryPos = this.entryPosById(entryId),
|
||||||
|
currentEntryEmbeds = this.domainObject.entries[entryPos].embeds,
|
||||||
|
newEmbed = {
|
||||||
|
type: selectedObjectId,
|
||||||
|
id: '' + Date.now(),
|
||||||
|
cssClass: cssClass,
|
||||||
|
name: selectedModel.name,
|
||||||
|
snapshot: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
currentEntryEmbeds.push(newEmbed);
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries[' + entryPos + '].embeds', currentEntryEmbeds);
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.dragoverOnEntry = function () {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.exposedData = function () {
|
||||||
|
return {
|
||||||
|
openmct: this.openmct,
|
||||||
|
domainObject: this.domainObject,
|
||||||
|
dndService: this.dndService,
|
||||||
|
dialogService: this.dialogService,
|
||||||
|
currentEntryValue: this.currentEntryValue
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
EntryController.prototype.exposedMethods = function () {
|
||||||
|
return {
|
||||||
|
entryPosById: this.entryPosById,
|
||||||
|
textFocus: this.textFocus,
|
||||||
|
textBlur: this.textBlur,
|
||||||
|
formatTime: this.formatTime,
|
||||||
|
deleteEntry: this.deleteEntry,
|
||||||
|
dropOnEntry: this.dropOnEntry,
|
||||||
|
dragoverOnEntry: this.dragoverOnEntry
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return EntryController;
|
||||||
|
});
|
@ -31,8 +31,7 @@ define(
|
|||||||
$scope.snapshot = undefined;
|
$scope.snapshot = undefined;
|
||||||
$scope.snapToggle = true;
|
$scope.snapToggle = true;
|
||||||
$scope.entryText = '';
|
$scope.entryText = '';
|
||||||
var annotateAction = $rootScope.selObj.getCapability('action').getActions(
|
var annotateAction = $rootScope.selObj.getCapability('action').getActions({key: 'annotate-snapshot'})[0];
|
||||||
{category: 'embed'})[1];
|
|
||||||
|
|
||||||
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = $rootScope.selObj;
|
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = $rootScope.selObj;
|
||||||
$scope.objectName = $rootScope.selObj.getModel().name;
|
$scope.objectName = $rootScope.selObj.getModel().name;
|
177
src/plugins/notebook/src/controllers/NotebookController.js
Normal file
177
src/plugins/notebook/src/controllers/NotebookController.js
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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',
|
||||||
|
'./EntryController',
|
||||||
|
'./EmbedController',
|
||||||
|
'../../res/templates/notebook.html',
|
||||||
|
'../../res/templates/entry.html',
|
||||||
|
'../../res/templates/embed.html',
|
||||||
|
'../../../../ui/components/controls/search.vue'
|
||||||
|
],
|
||||||
|
function (
|
||||||
|
Vue,
|
||||||
|
EntryController,
|
||||||
|
EmbedController,
|
||||||
|
NotebookTemplate,
|
||||||
|
EntryTemplate,
|
||||||
|
EmbedTemplate,
|
||||||
|
search
|
||||||
|
) {
|
||||||
|
|
||||||
|
function NotebookController(openmct, domainObject) {
|
||||||
|
this.openmct = openmct;
|
||||||
|
this.domainObject = domainObject;
|
||||||
|
this.entrySearch = '';
|
||||||
|
this.objectService = openmct.$injector.get('objectService');
|
||||||
|
this.actionService = openmct.$injector.get('actionService');
|
||||||
|
|
||||||
|
this.show = this.show.bind(this);
|
||||||
|
this.destroy = this.destroy.bind(this);
|
||||||
|
this.newEntry = this.newEntry.bind(this);
|
||||||
|
this.entryPosById = this.entryPosById.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
NotebookController.prototype.initializeVue = function (container) {
|
||||||
|
var self = this,
|
||||||
|
entryController = new EntryController(this.openmct, this.domainObject),
|
||||||
|
embedController = new EmbedController(this.openmct, this.domainObject);
|
||||||
|
|
||||||
|
this.container = container;
|
||||||
|
|
||||||
|
var notebookEmbed = {
|
||||||
|
props:['embed', 'entry'],
|
||||||
|
template: EmbedTemplate,
|
||||||
|
data: embedController.exposedData,
|
||||||
|
methods: embedController.exposedMethods(),
|
||||||
|
beforeMount: embedController.populateActionMenu(self.objectService, self.actionService)
|
||||||
|
};
|
||||||
|
|
||||||
|
var entryComponent = {
|
||||||
|
props:['entry'],
|
||||||
|
template: EntryTemplate,
|
||||||
|
components: {
|
||||||
|
'notebook-embed': notebookEmbed
|
||||||
|
},
|
||||||
|
data: entryController.exposedData,
|
||||||
|
methods: entryController.exposedMethods(),
|
||||||
|
mounted: self.focusOnEntry
|
||||||
|
};
|
||||||
|
|
||||||
|
var notebookVue = Vue.extend({
|
||||||
|
template: NotebookTemplate,
|
||||||
|
components: {
|
||||||
|
'notebook-entry': entryComponent,
|
||||||
|
'search': search.default
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
entrySearch: self.entrySearch,
|
||||||
|
showTime: '0',
|
||||||
|
sortEntries: '-createdOn',
|
||||||
|
entries: self.domainObject.entries,
|
||||||
|
currentEntryValue: ''
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
search: function (event) {
|
||||||
|
if (event.target.value) {
|
||||||
|
this.entrySearch = event.target.value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
newEntry: self.newEntry,
|
||||||
|
filterBySearch: self.filterBySearch
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.NotebookVue = new notebookVue();
|
||||||
|
container.appendChild(this.NotebookVue.$mount().$el);
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.newEntry = function (event) {
|
||||||
|
|
||||||
|
var entries = this.domainObject.entries,
|
||||||
|
lastEntryIndex = entries.length - 1,
|
||||||
|
lastEntry = entries[lastEntryIndex],
|
||||||
|
date = Date.now();
|
||||||
|
|
||||||
|
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds.length) {
|
||||||
|
var createdEntry = {'id': 'entry-' + date, 'createdOn': date, 'embeds':[]};
|
||||||
|
|
||||||
|
entries.push(createdEntry);
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries', entries);
|
||||||
|
} else {
|
||||||
|
lastEntry.createdOn = date;
|
||||||
|
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'entries[entries.length-1]', lastEntry);
|
||||||
|
this.focusOnEntry.bind(this.NotebookVue.$children[lastEntryIndex])();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.entrySearch = '';
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.entryPosById = function (entryId) {
|
||||||
|
var foundId = -1;
|
||||||
|
|
||||||
|
this.domainObject.entries.forEach(function (element, index) {
|
||||||
|
if (element.id === entryId) {
|
||||||
|
foundId = index;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return foundId;
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.focusOnEntry = function () {
|
||||||
|
if (!this.entry.text) {
|
||||||
|
this.$refs.contenteditable.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.filterBySearch = function (entryArray, filterString) {
|
||||||
|
if (filterString) {
|
||||||
|
var lowerCaseFilterString = filterString.toLowerCase();
|
||||||
|
|
||||||
|
return entryArray.filter(function (entry) {
|
||||||
|
if (entry.text) {
|
||||||
|
return entry.text.toLowerCase().includes(lowerCaseFilterString);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return entryArray;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.show = function (container) {
|
||||||
|
this.initializeVue(container);
|
||||||
|
};
|
||||||
|
|
||||||
|
NotebookController.prototype.destroy = function (container) {
|
||||||
|
this.NotebookVue.$destroy(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
return NotebookController;
|
||||||
|
});
|
@ -31,9 +31,11 @@ define(['zepto'], function ($) {
|
|||||||
var selectedModel = selectedObject.getModel();
|
var selectedModel = selectedObject.getModel();
|
||||||
var cssClass = selectedObject.getCapability('type').typeDef.cssClass;
|
var cssClass = selectedObject.getCapability('type').typeDef.cssClass;
|
||||||
var entryId = -1;
|
var entryId = -1;
|
||||||
|
var embedId = -1;
|
||||||
$scope.clearSearch();
|
$scope.clearSearch();
|
||||||
if ($element[0].id === 'newEntry') {
|
if ($element[0].id === 'newEntry') {
|
||||||
entryId = $scope.domainObject.model.entries.length;
|
entryId = $scope.domainObject.model.entries.length;
|
||||||
|
embedId = 0;
|
||||||
var lastEntry = $scope.domainObject.model.entries[entryId - 1];
|
var lastEntry = $scope.domainObject.model.entries[entryId - 1];
|
||||||
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds) {
|
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds) {
|
||||||
$scope.domainObject.useCapability('mutation', function (model) {
|
$scope.domainObject.useCapability('mutation', function (model) {
|
||||||
@ -82,6 +84,8 @@ define(['zepto'], function ($) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
embedId = $scope.domainObject.model.entries[entryId].embeds.length - 1;
|
||||||
|
|
||||||
if (selectedObject) {
|
if (selectedObject) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
@ -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
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
* Administration. All rights reserved.
|
* Administration. All rights reserved.
|
||||||
*
|
*
|
||||||
@ -20,35 +20,47 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
/**
|
|
||||||
* This bundle implements object types and associated views for
|
|
||||||
* display-building.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
define([
|
||||||
* The LayoutNotebookController is responsible for supporting the
|
'vue',
|
||||||
* notebook feature creation on theLayout view.
|
'../../res/templates/viewSnapshot.html'
|
||||||
**/
|
], function (
|
||||||
|
Vue,
|
||||||
|
snapshotOverlayTemplate
|
||||||
|
) {
|
||||||
|
function SnapshotOverlay (embedObject, formatTime) {
|
||||||
|
this.embedObject = embedObject;
|
||||||
|
|
||||||
function LayoutNotebookController($scope) {
|
this.snapshotOverlayVue = new Vue({
|
||||||
$scope.hasNotebookAction = undefined;
|
template: snapshotOverlayTemplate,
|
||||||
|
data: function () {
|
||||||
$scope.newNotebook = undefined;
|
return {
|
||||||
|
embed: embedObject
|
||||||
var actions = $scope.domainObject.getCapability('action');
|
|
||||||
var notebookAction = actions.getActions({'key': 'notebook-new-entry'});
|
|
||||||
if (notebookAction.length > 0) {
|
|
||||||
$scope.hasNotebookAction = true;
|
|
||||||
$scope.newNotebook = function () {
|
|
||||||
notebookAction[0].perform();
|
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
close: this.close.bind(this),
|
||||||
|
formatTime: formatTime
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.open();
|
||||||
}
|
}
|
||||||
|
|
||||||
return LayoutNotebookController;
|
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;
|
||||||
|
});
|
@ -27,14 +27,15 @@ define([
|
|||||||
'./autoflow/AutoflowTabularPlugin',
|
'./autoflow/AutoflowTabularPlugin',
|
||||||
'./timeConductor/plugin',
|
'./timeConductor/plugin',
|
||||||
'../../example/imagery/plugin',
|
'../../example/imagery/plugin',
|
||||||
'../../platform/features/notebook/bundle',
|
|
||||||
'../../platform/import-export/bundle',
|
'../../platform/import-export/bundle',
|
||||||
'./summaryWidget/plugin',
|
'./summaryWidget/plugin',
|
||||||
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
||||||
'./telemetryMean/plugin',
|
'./telemetryMean/plugin',
|
||||||
'./plot/plugin',
|
'./plot/plugin',
|
||||||
'./telemetryTable/plugin',
|
'./telemetryTable/plugin',
|
||||||
'./staticRootPlugin/plugin'
|
'./staticRootPlugin/plugin',
|
||||||
|
'./notebook/plugin',
|
||||||
|
'./displayLayout/plugin'
|
||||||
], function (
|
], function (
|
||||||
_,
|
_,
|
||||||
UTCTimeSystem,
|
UTCTimeSystem,
|
||||||
@ -42,19 +43,19 @@ define([
|
|||||||
AutoflowPlugin,
|
AutoflowPlugin,
|
||||||
TimeConductorPlugin,
|
TimeConductorPlugin,
|
||||||
ExampleImagery,
|
ExampleImagery,
|
||||||
Notebook,
|
|
||||||
ImportExport,
|
ImportExport,
|
||||||
SummaryWidget,
|
SummaryWidget,
|
||||||
URLIndicatorPlugin,
|
URLIndicatorPlugin,
|
||||||
TelemetryMean,
|
TelemetryMean,
|
||||||
PlotPlugin,
|
PlotPlugin,
|
||||||
TelemetryTablePlugin,
|
TelemetryTablePlugin,
|
||||||
StaticRootPlugin
|
StaticRootPlugin,
|
||||||
|
Notebook,
|
||||||
|
DisplayLayoutPlugin
|
||||||
) {
|
) {
|
||||||
var bundleMap = {
|
var bundleMap = {
|
||||||
LocalStorage: 'platform/persistence/local',
|
LocalStorage: 'platform/persistence/local',
|
||||||
MyItems: 'platform/features/my-items',
|
MyItems: 'platform/features/my-items'
|
||||||
Notebook: 'platform/features/notebook'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var plugins = _.mapValues(bundleMap, function (bundleName, pluginName) {
|
var plugins = _.mapValues(bundleMap, function (bundleName, pluginName) {
|
||||||
@ -159,6 +160,8 @@ define([
|
|||||||
plugins.SummaryWidget = SummaryWidget;
|
plugins.SummaryWidget = SummaryWidget;
|
||||||
plugins.TelemetryMean = TelemetryMean;
|
plugins.TelemetryMean = TelemetryMean;
|
||||||
plugins.URLIndicator = URLIndicatorPlugin;
|
plugins.URLIndicator = URLIndicatorPlugin;
|
||||||
|
plugins.Notebook = Notebook;
|
||||||
|
plugins.DisplayLayout = DisplayLayoutPlugin.default;
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
@ -15,7 +15,8 @@ define([
|
|||||||
function SummaryWidgetViewProvider(openmct) {
|
function SummaryWidgetViewProvider(openmct) {
|
||||||
return {
|
return {
|
||||||
key: 'summary-widget-viewer',
|
key: 'summary-widget-viewer',
|
||||||
name: 'Widget View',
|
name: 'Summary View',
|
||||||
|
cssClass: 'icon-summary-widget',
|
||||||
canView: function (domainObject) {
|
canView: function (domainObject) {
|
||||||
return domainObject.type === 'summary-widget';
|
return domainObject.type === 'summary-widget';
|
||||||
},
|
},
|
||||||
|
@ -30,10 +30,9 @@ define([], function () {
|
|||||||
this.objectKeyString = objectKeyString;
|
this.objectKeyString = objectKeyString;
|
||||||
}
|
}
|
||||||
|
|
||||||
getFormattedDatum() {
|
getFormattedDatum(headers) {
|
||||||
return Object.values(this.columns)
|
return Object.keys(headers).reduce((formattedDatum, columnKey) => {
|
||||||
.reduce((formattedDatum, column) => {
|
formattedDatum[columnKey] = this.getFormattedValue(columnKey);
|
||||||
formattedDatum[column.getKey()] = this.getFormattedValue(column.getKey());
|
|
||||||
return formattedDatum;
|
return formattedDatum;
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
@ -35,12 +35,15 @@ define([
|
|||||||
return {
|
return {
|
||||||
key: 'table',
|
key: 'table',
|
||||||
name: 'Telemetry Table',
|
name: 'Telemetry Table',
|
||||||
editable: true,
|
cssClass: 'icon-tabular-realtime',
|
||||||
|
editable: function(domainObject) {
|
||||||
|
return domainObject.type === 'table';
|
||||||
|
},
|
||||||
canView: function (domainObject) {
|
canView: function (domainObject) {
|
||||||
return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
|
return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
|
||||||
},
|
},
|
||||||
view: function (domainObject) {
|
view: function (domainObject) {
|
||||||
let csvExporter = new CSVExporter();
|
let csvExporter = new CSVExporter.default();
|
||||||
let table = new TelemetryTable(domainObject, openmct);
|
let table = new TelemetryTable(domainObject, openmct);
|
||||||
let component;
|
let component;
|
||||||
return {
|
return {
|
||||||
|
@ -82,8 +82,7 @@ define(
|
|||||||
// Going to check for duplicates. Bound the search problem to
|
// Going to check for duplicates. Bound the search problem to
|
||||||
// items around the given time. Use sortedIndex because it
|
// items around the given time. Use sortedIndex because it
|
||||||
// employs a binary search which is O(log n). Can use binary search
|
// employs a binary search which is O(log n). Can use binary search
|
||||||
// based on time stamp because the array is guaranteed ordered due
|
// because the array is guaranteed ordered due to sorted insertion.
|
||||||
// to sorted insertion.
|
|
||||||
let startIx = this.sortedIndex(this.rows, row);
|
let startIx = this.sortedIndex(this.rows, row);
|
||||||
let endIx = undefined;
|
let endIx = undefined;
|
||||||
|
|
||||||
@ -113,15 +112,37 @@ define(
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
sortedIndex(rows, testRow, lodashFunction) {
|
sortedIndex(rows, testRow, lodashFunction) {
|
||||||
|
if (this.rows.length === 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const sortOptionsKey = this.sortOptions.key;
|
const sortOptionsKey = this.sortOptions.key;
|
||||||
|
const testRowValue = testRow.datum[sortOptionsKey];
|
||||||
|
const firstValue = this.rows[0].datum[sortOptionsKey];
|
||||||
|
const lastValue = this.rows[this.rows.length - 1].datum[sortOptionsKey];
|
||||||
|
|
||||||
lodashFunction = lodashFunction || _.sortedIndex;
|
lodashFunction = lodashFunction || _.sortedIndex;
|
||||||
|
|
||||||
if (this.sortOptions.direction === 'asc') {
|
if (this.sortOptions.direction === 'asc') {
|
||||||
|
if (testRowValue > lastValue) {
|
||||||
|
return this.rows.length;
|
||||||
|
} else if (testRowValue === lastValue) {
|
||||||
|
return this.rows.length - 1;
|
||||||
|
} else if (testRowValue <= firstValue) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
return lodashFunction(rows, testRow, (thisRow) => {
|
||||||
return thisRow.datum[sortOptionsKey];
|
return thisRow.datum[sortOptionsKey];
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (testRowValue >= firstValue) {
|
||||||
|
return 0;
|
||||||
|
} else if (testRowValue < lastValue) {
|
||||||
|
return this.rows.length;
|
||||||
|
} else if (testRowValue === lastValue) {
|
||||||
|
return this.rows.length - 1;
|
||||||
} else {
|
} else {
|
||||||
const testRowValue = testRow.datum[this.sortOptions.key];
|
|
||||||
// Use a custom comparison function to support descending sort.
|
// Use a custom comparison function to support descending sort.
|
||||||
return lodashFunction(rows, testRow, (thisRow) => {
|
return lodashFunction(rows, testRow, (thisRow) => {
|
||||||
const thisRowValue = thisRow.datum[sortOptionsKey];
|
const thisRowValue = thisRow.datum[sortOptionsKey];
|
||||||
@ -135,6 +156,7 @@ define(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sorts the telemetry collection based on the provided sort field
|
* Sorts the telemetry collection based on the provided sort field
|
||||||
|
@ -15,7 +15,7 @@ export default {
|
|||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
|
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
|
||||||
formattedRow: this.row.getFormattedDatum(),
|
formattedRow: this.row.getFormattedDatum(this.headers),
|
||||||
rowLimitClass: this.row.getRowLimitClass(),
|
rowLimitClass: this.row.getRowLimitClass(),
|
||||||
cellLimitClasses: this.row.getCellLimitClasses()
|
cellLimitClasses: this.row.getCellLimitClasses()
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ export default {
|
|||||||
this.rowTop = (rowOffset + this.rowIndex) * this.rowHeight + 'px';
|
this.rowTop = (rowOffset + this.rowIndex) * this.rowHeight + 'px';
|
||||||
},
|
},
|
||||||
formatRow: function (row) {
|
formatRow: function (row) {
|
||||||
this.formattedRow = row.getFormattedDatum();
|
this.formattedRow = row.getFormattedDatum(this.headers);
|
||||||
this.rowLimitClass = row.getRowLimitClass();
|
this.rowLimitClass = row.getRowLimitClass();
|
||||||
this.cellLimitClasses = row.getCellLimitClasses();
|
this.cellLimitClasses = row.getCellLimitClasses();
|
||||||
}
|
}
|
||||||
|
@ -19,16 +19,16 @@
|
|||||||
:class="['is-sortable', sortOptions.key === key ? 'is-sorting' : '', sortOptions.direction].join(' ')"
|
:class="['is-sortable', sortOptions.key === key ? 'is-sorting' : '', sortOptions.direction].join(' ')"
|
||||||
:style="{ width: columnWidths[headerIndex], 'max-width': columnWidths[headerIndex]}">{{title}}</th>
|
:style="{ width: columnWidths[headerIndex], 'max-width': columnWidths[headerIndex]}">{{title}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="s-filters">
|
<tr>
|
||||||
<th v-for="(title, key, headerIndex) in headers"
|
<th v-for="(title, key, headerIndex) in headers"
|
||||||
:style="{
|
:style="{
|
||||||
width: columnWidths[headerIndex],
|
width: columnWidths[headerIndex],
|
||||||
'max-width': columnWidths[headerIndex],
|
'max-width': columnWidths[headerIndex],
|
||||||
}">
|
}">
|
||||||
<div class="holder l-filter flex-elem grows" :class="{active: filters[key]}">
|
<search class="c-table__search"
|
||||||
<input type="text" v-model="filters[key]" v-on:input="filterChanged(key)" />
|
v-model="filters[key]"
|
||||||
<a class="clear-icon clear-input icon-x-in-circle" :class="{show: filters[key]}" @click="clearFilter(key)"></a>
|
v-on:input="filterChanged(key)"
|
||||||
</div>
|
v-on:clear="clearFilter(key)" />
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -266,6 +266,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import TelemetryTableRow from './table-row.vue';
|
import TelemetryTableRow from './table-row.vue';
|
||||||
|
import search from '../../../ui/components/controls/search.vue';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
const VISIBLE_ROW_COUNT = 100;
|
const VISIBLE_ROW_COUNT = 100;
|
||||||
@ -275,14 +276,14 @@ const AUTO_SCROLL_TRIGGER_HEIGHT = 20;
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
TelemetryTableRow
|
TelemetryTableRow,
|
||||||
|
search
|
||||||
},
|
},
|
||||||
inject: ['table', 'openmct', 'csvExporter'],
|
inject: ['table', 'openmct', 'csvExporter'],
|
||||||
props: ['configuration'],
|
props: ['configuration'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
headers: {},
|
headers: {},
|
||||||
headersCount: 0,
|
|
||||||
visibleRows: [],
|
visibleRows: [],
|
||||||
columnWidths: [],
|
columnWidths: [],
|
||||||
sizingRows: {},
|
sizingRows: {},
|
||||||
@ -346,7 +347,6 @@ export default {
|
|||||||
let headers = this.table.configuration.getVisibleHeaders();
|
let headers = this.table.configuration.getVisibleHeaders();
|
||||||
|
|
||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
this.headersCount = Object.values(headers).length;
|
|
||||||
this.$nextTick().then(this.calculateColumnWidths);
|
this.$nextTick().then(this.calculateColumnWidths);
|
||||||
},
|
},
|
||||||
setSizingTableWidth() {
|
setSizingTableWidth() {
|
||||||
@ -454,12 +454,12 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
exportAsCSV() {
|
exportAsCSV() {
|
||||||
|
const headerKeys = Object.keys(this.headers);
|
||||||
const justTheData = this.table.filteredRows.getRows()
|
const justTheData = this.table.filteredRows.getRows()
|
||||||
.map(row => row.getFormattedDatum());
|
.map(row => row.getFormattedDatum(this.headers));
|
||||||
const headers = Object.keys(this.headers);
|
|
||||||
this.csvExporter.export(justTheData, {
|
this.csvExporter.export(justTheData, {
|
||||||
filename: this.table.domainObject.name + '.csv',
|
filename: this.table.domainObject.name + '.csv',
|
||||||
headers: headers
|
headers: headerKeys
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
outstandingRequests(loading) {
|
outstandingRequests(loading) {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
@import "constants";
|
@import "constants";
|
||||||
|
|
||||||
// Mixins
|
// Functions
|
||||||
@function pullForward($c: $colorBodyBg, $p: 20%) {
|
@function pullForward($c: $colorBodyBg, $p: 20%) {
|
||||||
// For dark interfaces, lighter things come forward - opposite for light interfaces
|
// For dark interfaces, lighter things come forward - opposite for light interfaces
|
||||||
@return darken($c, $p);
|
@return darken($c, $p);
|
||||||
@ -12,7 +12,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Global
|
// Global
|
||||||
$fontBaseSize: 13px;
|
$fontBaseSize: 12px;
|
||||||
$colorBodyBg: #fcfcfc;
|
$colorBodyBg: #fcfcfc;
|
||||||
$colorBodyFg: #666;
|
$colorBodyFg: #666;
|
||||||
$colorGenBg: #fff;
|
$colorGenBg: #fff;
|
||||||
@ -49,6 +49,9 @@ $colorBtnMajorBg: $colorKey;
|
|||||||
$colorBtnMajorBgHov: $colorKeyHov;
|
$colorBtnMajorBgHov: $colorKeyHov;
|
||||||
$colorBtnMajorFg: $colorKeyFg;
|
$colorBtnMajorFg: $colorKeyFg;
|
||||||
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, $hoverRatioPercent);
|
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, $hoverRatioPercent);
|
||||||
|
$colorBtnCautionBg: #f16f6f;
|
||||||
|
$colorBtnCautionBgHov: #f1504e;
|
||||||
|
$colorBtnCautionFg: $colorBtnFg;
|
||||||
$colorClickIcon: $colorKey;
|
$colorClickIcon: $colorKey;
|
||||||
$colorClickIconHov: $colorKeyHov;
|
$colorClickIconHov: $colorKeyHov;
|
||||||
$colorToggleIcon: rgba($colorClickIcon, 0.5);
|
$colorToggleIcon: rgba($colorClickIcon, 0.5);
|
||||||
@ -71,6 +74,7 @@ $sliderKnobR: 2px;
|
|||||||
$timeControllerToiLineColor: $colorBodyFg;
|
$timeControllerToiLineColor: $colorBodyFg;
|
||||||
$timeControllerToiLineColorHov: #0052b5;
|
$timeControllerToiLineColorHov: #0052b5;
|
||||||
$colorTransLucBg: #666; // Used as a visual blocking element over variable backgrounds, like imagery
|
$colorTransLucBg: #666; // Used as a visual blocking element over variable backgrounds, like imagery
|
||||||
|
$createBtnTextTransform: uppercase;
|
||||||
|
|
||||||
// Foundation Colors
|
// Foundation Colors
|
||||||
$colorAlt1: #776ba2;
|
$colorAlt1: #776ba2;
|
||||||
@ -106,6 +110,11 @@ $colorCreateMenuLgIcon: $colorKey;
|
|||||||
$colorCreateMenuText: $colorBodyFg;
|
$colorCreateMenuText: $colorBodyFg;
|
||||||
$menuItemPad: ($interiorMargin, nth($btnPad, 2));
|
$menuItemPad: ($interiorMargin, nth($btnPad, 2));
|
||||||
|
|
||||||
|
// Palettes and Swatches
|
||||||
|
$paletteItemBorderOuterColorSelected: black;
|
||||||
|
$paletteItemBorderInnerColorSelected: white;
|
||||||
|
$paletteItemBorderInnerColor: rgba($paletteItemBorderOuterColorSelected, 0.3);
|
||||||
|
|
||||||
// Form colors
|
// Form colors
|
||||||
$colorCheck: $colorKey;
|
$colorCheck: $colorKey;
|
||||||
$colorFormRequired: $colorKey;
|
$colorFormRequired: $colorKey;
|
||||||
@ -277,12 +286,6 @@ $colorCalCellSelectedBg: $colorItemTreeSelectedBg;
|
|||||||
$colorCalCellSelectedFg: $colorItemTreeSelectedFg;
|
$colorCalCellSelectedFg: $colorItemTreeSelectedFg;
|
||||||
$colorCalCellInMonthBg: pullForward($colorMenuBg, 5%);
|
$colorCalCellInMonthBg: pullForward($colorMenuBg, 5%);
|
||||||
|
|
||||||
// Palettes
|
|
||||||
$colorPaletteFg: pullForward($colorMenuBg, 30%);
|
|
||||||
$colorPaletteSelected: #333;
|
|
||||||
$shdwPaletteFg: none;
|
|
||||||
$shdwPaletteSelected: inset 0 0 0 1px #fff;
|
|
||||||
|
|
||||||
// About Screen
|
// About Screen
|
||||||
$colorAboutLink: #84b3ff;
|
$colorAboutLink: #84b3ff;
|
||||||
|
|
||||||
@ -293,3 +296,16 @@ $colorLoadingBg: rgba($colorLoadingFg, 0.1);
|
|||||||
// Transitions
|
// Transitions
|
||||||
$transIn: all 50ms ease-in;
|
$transIn: all 50ms ease-in;
|
||||||
$transOut: all 250ms ease-out;
|
$transOut: all 250ms ease-out;
|
||||||
|
|
||||||
|
// Discrete items, like Notebook entries, Widget rules
|
||||||
|
@mixin discreteItem() {
|
||||||
|
background: rgba($colorBodyFg,0.1);
|
||||||
|
border: 1px solid $colorInteriorBorder;
|
||||||
|
border-radius: $controlCr;
|
||||||
|
.c-input-inline:hover {
|
||||||
|
background: $colorBodyBg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@mixin discreteItemInnerElem() {
|
||||||
|
border: 1px solid $colorBodyBg;
|
||||||
|
border-radius: $controlCr; }
|
||||||
|
@ -96,7 +96,7 @@ $glyph-icon-pointer-right: '\e1028';
|
|||||||
$glyph-icon-refresh: '\e1029';
|
$glyph-icon-refresh: '\e1029';
|
||||||
$glyph-icon-save: '\e1030';
|
$glyph-icon-save: '\e1030';
|
||||||
$glyph-icon-sine: '\e1031';
|
$glyph-icon-sine: '\e1031';
|
||||||
$glyph-icon-T: '\e1032';
|
$glyph-icon-font: '\e1032';
|
||||||
$glyph-icon-thumbs-strip: '\e1033';
|
$glyph-icon-thumbs-strip: '\e1033';
|
||||||
$glyph-icon-two-parts-both: '\e1034';
|
$glyph-icon-two-parts-both: '\e1034';
|
||||||
$glyph-icon-two-parts-one-only: '\e1035';
|
$glyph-icon-two-parts-one-only: '\e1035';
|
||||||
@ -113,7 +113,7 @@ $glyph-icon-frame-show: '\e1045';
|
|||||||
$glyph-icon-frame-hide: '\e1046';
|
$glyph-icon-frame-hide: '\e1046';
|
||||||
$glyph-icon-import: '\e1047';
|
$glyph-icon-import: '\e1047';
|
||||||
$glyph-icon-export: '\e1048';
|
$glyph-icon-export: '\e1048';
|
||||||
$glyph-icon-minimize: '\e1049'; // 12px only
|
$glyph-icon-font-size: '\e1049';
|
||||||
$glyph-icon-activity: '\e1100';
|
$glyph-icon-activity: '\e1100';
|
||||||
$glyph-icon-activity-mode: '\e1101';
|
$glyph-icon-activity-mode: '\e1101';
|
||||||
$glyph-icon-autoflow-tabular: '\e1102';
|
$glyph-icon-autoflow-tabular: '\e1102';
|
||||||
|
@ -1,10 +1,35 @@
|
|||||||
/**************************** BUTTONS */
|
/*****************************************************************************
|
||||||
%c-control {
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// VERSION MANUALLY RESTORED FROM VUE-LAYOUT
|
||||||
|
|
||||||
|
/******************************************************** PLACEHOLDERS */
|
||||||
|
@mixin cControl() {
|
||||||
|
$fs: 1em;
|
||||||
@include userSelectNone();
|
@include userSelectNone();
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: start;
|
justify-content: center;
|
||||||
cursor: pointer;
|
overflow: hidden;
|
||||||
|
|
||||||
&:before,
|
&:before,
|
||||||
&:after {
|
&:after {
|
||||||
@ -13,21 +38,24 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:before {
|
&:after {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
[class*="__label"] {
|
||||||
font-size: 0.6em;
|
@include ellipsize();
|
||||||
|
display: block;
|
||||||
|
line-height: $fs; // Remove effect on top and bottom padding
|
||||||
|
font-size: $fs;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@mixin cButton() {
|
||||||
|
@include cControl();
|
||||||
%c-button {
|
|
||||||
@extend %c-control;
|
|
||||||
background: $colorBtnBg;
|
background: $colorBtnBg;
|
||||||
border-radius: $controlCr;
|
border-radius: $controlCr;
|
||||||
color: $colorBtnFg;
|
color: $colorBtnFg;
|
||||||
|
cursor: pointer;
|
||||||
padding: nth($btnPad, 1) nth($btnPad, 2);
|
padding: nth($btnPad, 1) nth($btnPad, 2);
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -44,97 +72,224 @@
|
|||||||
color: $colorBtnMajorFgHov;
|
color: $colorBtnMajorFgHov;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[class*='--caution'] {
|
||||||
|
background: $colorBtnCautionBg;
|
||||||
|
color: $colorBtnCautionFg;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $colorBtnCautionBgHov;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********* Buttons */
|
@mixin cClickIcon() {
|
||||||
// Optionally can include icon in :before
|
|
||||||
.c-button {
|
|
||||||
@extend %c-button;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********* Icon Buttons */
|
|
||||||
.c-icon-button {
|
|
||||||
// A clickable element that just includes the icon, no background
|
// A clickable element that just includes the icon, no background
|
||||||
// Padding is included to facilitate a bigger hit area
|
// Padding is included to facilitate a bigger hit area
|
||||||
@extend %c-control;
|
// Make the icon bigger relative to its container
|
||||||
|
@include cControl();
|
||||||
|
$pLR: 3px;
|
||||||
|
$pTB: 3px;
|
||||||
border-radius: $controlCr;
|
border-radius: $controlCr;
|
||||||
color: $colorKey;
|
color: $colorKey;
|
||||||
padding: nth($btnPad, 1) floor(nth($btnPad, 2) * 0.8);
|
cursor: pointer;
|
||||||
|
padding: $pTB $pLR ;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba($colorKey, 0.2);
|
background: rgba($colorKey, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:before {
|
&:before,
|
||||||
font-size: 1.1em;
|
*:before {
|
||||||
|
// *:before handles any nested containers that may contain glyph elements
|
||||||
|
// Needed for c-togglebutton.
|
||||||
|
font-size: 1.3em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********* Button Sets */
|
@mixin cCtrlWrapper {
|
||||||
.c-button-set {
|
// Provides a wrapper around buttons and other controls
|
||||||
// Buttons are smashed together with minimal margin
|
// Contains control and provides positioning context for contained menu/palette.
|
||||||
// c-buttons don't have border-radius between buttons, creates a tool-button-strip look
|
// Wraps --menu elements, contains button and menu
|
||||||
// c-icon-buttons get grouped more closely together
|
overflow: visible;
|
||||||
// When one set is adjacent to another, provides a divider between
|
|
||||||
|
|
||||||
display: flex;
|
.c-menu {
|
||||||
|
// Default position of contained menu
|
||||||
|
top: 100%; left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&[class*='--menus-up'] {
|
||||||
|
.c-menu {
|
||||||
|
top: auto; bottom: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[class*='--menus-left'] {
|
||||||
|
.c-menu {
|
||||||
|
left: auto; right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********* Buttons */
|
||||||
|
// Optionally can include icon in :before via markup
|
||||||
|
.c-button,
|
||||||
|
.c-button--menu,
|
||||||
|
button {
|
||||||
|
@include cButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-button--menu {
|
||||||
|
$m: $interiorMargin;
|
||||||
|
|
||||||
|
&:before,
|
||||||
> * {
|
> * {
|
||||||
// Assume buttons are immediate descendants
|
|
||||||
flex: 0 0 auto;
|
|
||||||
|
|
||||||
&[class^="c-button"] {
|
|
||||||
// Only apply the following to buttons that have background, eg. c-button
|
|
||||||
border-radius: 0;
|
|
||||||
|
|
||||||
+ * {
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:first-child {
|
|
||||||
border-top-left-radius: $controlCr;
|
|
||||||
border-bottom-left-radius: $controlCr;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-top-right-radius: $controlCr;
|
|
||||||
border-bottom-right-radius: $controlCr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ .c-button-set {
|
|
||||||
$m: $interiorMarginSm;
|
|
||||||
&:before {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
width: $m;
|
|
||||||
border-right: 1px solid $colorInteriorBorder;
|
|
||||||
margin-right: $m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/********* Menu Buttons */
|
|
||||||
// Always includes :after dropdown arrow
|
|
||||||
// Optionally can include icon in :before
|
|
||||||
.c-menu-button {
|
|
||||||
$m: $interiorMarginSm;
|
|
||||||
@extend %c-button;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
margin-right: $m;
|
margin-right: $m;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: $glyph-icon-arrow-down;
|
content: $glyph-icon-arrow-down;
|
||||||
font-family: symbolsfont;
|
font-family: symbolsfont;
|
||||||
margin-left: $m;
|
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** MENUS */
|
/********* Icon Buttons */
|
||||||
|
.c-click-icon {
|
||||||
|
@include cClickIcon();
|
||||||
|
|
||||||
|
&--menu {
|
||||||
|
&:after {
|
||||||
|
content: $glyph-icon-arrow-down;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 0.6em;
|
||||||
|
margin-left: floor($interiorMarginSm * 0.8);
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--swatched {
|
||||||
|
// Color control, show swatch element
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
> [class*='swatch'] {
|
||||||
|
box-shadow: inset rgba(black, 0.2) 0 0 1px;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
height: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Reduce size of icon to make a bit of room
|
||||||
|
flex: 1 1 auto;
|
||||||
|
font-size: 1.1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** DISCLOSURE CONTROLS */
|
||||||
|
/********* Disclosure Button */
|
||||||
|
// Provides a downward arrow icon that when clicked displays a context menu
|
||||||
|
// Always placed AFTER an element
|
||||||
|
.c-disclosure-button {
|
||||||
|
@include cClickIcon();
|
||||||
|
margin-left: $interiorMarginSm;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: $glyph-icon-arrow-down;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 0.7em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/********* Disclosure Triangle */
|
||||||
|
// Provides an arrow icon that when clicked expands an element to reveal its contents.
|
||||||
|
// Used in tree items. Always placed BEFORE an element.
|
||||||
|
.c-disclosure-triangle {
|
||||||
|
$d: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
width: $d;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&.is-enabled:before {
|
||||||
|
$s: .65;
|
||||||
|
content: $glyph-icon-arrow-right-equilateral;
|
||||||
|
display: block;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 1rem * $s;
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: floor(($d / 2) * $s); // This is slightly better than 'center'
|
||||||
|
transition: transform 100ms ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--expanded {
|
||||||
|
&:before {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************** FORM ELEMENTS */
|
||||||
|
/********* Inline inputs */
|
||||||
|
.c-input-inline {
|
||||||
|
// A text input or contenteditable element that indicates edit affordance on hover and looks like an input on focus
|
||||||
|
@include input-base();
|
||||||
|
border: 1px solid transparent;
|
||||||
|
display: block !important;
|
||||||
|
min-width: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 250ms ease;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:not(:focus) {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus {
|
||||||
|
padding-left: $inputTextPLeftRight;
|
||||||
|
padding-right: $inputTextPLeftRight;
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
border-color: rgba($colorBodyFg, 0.2);
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
@include nice-input($shdw: rgba(0, 0, 0, 0.6) 0 1px 3px);
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-labeled-input {
|
||||||
|
// An input used in the Toolbar
|
||||||
|
// Assumes label is before the input
|
||||||
|
@include cControl();
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-left: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
||||||
|
.c-hyperlink {
|
||||||
|
&--link {
|
||||||
|
color: $colorKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--button {
|
||||||
|
@include cButton();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** MENUS */
|
||||||
@mixin menuOuter() {
|
@mixin menuOuter() {
|
||||||
border-radius: $basicCr;
|
border-radius: $basicCr;
|
||||||
background: $colorMenuBg;
|
background: $colorMenuBg;
|
||||||
@ -149,7 +304,8 @@
|
|||||||
@mixin menuInner() {
|
@mixin menuInner() {
|
||||||
color: $colorMenuFg;
|
color: $colorMenuFg;
|
||||||
li {
|
li {
|
||||||
@extend %c-control;
|
@include cControl();
|
||||||
|
justify-content: start;
|
||||||
color: $colorMenuFg;
|
color: $colorMenuFg;
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: nth($menuItemPad, 1) nth($menuItemPad, 2);
|
padding: nth($menuItemPad, 1) nth($menuItemPad, 2);
|
||||||
@ -171,16 +327,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.c-menu {
|
.c-menu {
|
||||||
@include menuOuter();
|
@include menuOuter();
|
||||||
@include menuInner();
|
@include menuInner();
|
||||||
li {
|
|
||||||
&:not(:first-child) {
|
|
||||||
border-top: 1px solid pullForward($colorMenuBg, 10%);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-super-menu {
|
.c-super-menu {
|
||||||
@ -249,3 +398,155 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************** PALETTES */
|
||||||
|
.c-palette {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
|
||||||
|
&__items {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(10, [col] auto );
|
||||||
|
grid-gap: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
$d: 16px;
|
||||||
|
|
||||||
|
border: 1px solid transparent;
|
||||||
|
cursor: pointer;
|
||||||
|
width: 16px; height: 16px;
|
||||||
|
transition: $transOut;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
transition: $transIn;
|
||||||
|
$o: 0.7;
|
||||||
|
border-color: rgba($paletteItemBorderOuterColorSelected, $o);
|
||||||
|
box-shadow: inset rgba($paletteItemBorderInnerColorSelected, $o) 0 0 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-selected {
|
||||||
|
border-color: $paletteItemBorderOuterColorSelected !important;
|
||||||
|
border-width: 2px;
|
||||||
|
box-shadow: inset rgba($paletteItemBorderInnerColorSelected, 1) 0 0 0 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__item-none {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: $interiorMarginSm;
|
||||||
|
|
||||||
|
.c-palette__item {
|
||||||
|
@include noColor();
|
||||||
|
border-color: $paletteItemBorderInnerColor;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************** TOOLBAR */
|
||||||
|
.c-ctrl-wrapper {
|
||||||
|
@include cCtrlWrapper();
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-toolbar,
|
||||||
|
.c-toolbar .c-ctrl-wrapper {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-toolbar {
|
||||||
|
height: 24px; // Need to standardize the height
|
||||||
|
|
||||||
|
.c-click-icon {
|
||||||
|
@include cControl();
|
||||||
|
$pLR: $interiorMargin - 1;
|
||||||
|
$pTB: 2px;
|
||||||
|
color: $colorBodyFg;
|
||||||
|
padding: $pTB $pLR;
|
||||||
|
|
||||||
|
&--swatched {
|
||||||
|
padding-bottom: floor($pTB / 2);
|
||||||
|
width: 2em; // Standardize the width
|
||||||
|
}
|
||||||
|
|
||||||
|
&[class*='--caution'] {
|
||||||
|
&:before {
|
||||||
|
color: $colorBtnCautionBg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($colorBtnCautionBgHov, 0.2);
|
||||||
|
:before {
|
||||||
|
color: $colorBtnCautionBgHov;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-labeled-input {
|
||||||
|
font-size: 0.9em;
|
||||||
|
input[type='number'] {
|
||||||
|
width: 40px; // Number input sucks and must have size set using this method
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .c-labeled-input {
|
||||||
|
margin-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/********* Button Sets */
|
||||||
|
.c-button-set {
|
||||||
|
// When one set is adjacent to another, provides a divider between
|
||||||
|
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
> * {
|
||||||
|
// Assume buttons are immediate descendants
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
+ * {
|
||||||
|
// margin-left: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ .c-button-set {
|
||||||
|
$m: $interiorMargin;
|
||||||
|
$b: 1px;
|
||||||
|
&:before {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
width: $m + $b; // Allow for border
|
||||||
|
border-right: $b solid $colorInteriorBorder;
|
||||||
|
margin-right: $m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[class*='--strip'] {
|
||||||
|
// Buttons are smashed together with minimal margin
|
||||||
|
// c-buttons don't have border-radius between buttons, creates a tool-button-strip look
|
||||||
|
// c-click-icons get grouped more closely together
|
||||||
|
&[class^="c-button"] {
|
||||||
|
// Only apply the following to buttons that have background, eg. c-button
|
||||||
|
border-radius: 0;
|
||||||
|
|
||||||
|
+ * {
|
||||||
|
margin-left: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
border-top-left-radius: $controlCr;
|
||||||
|
border-bottom-left-radius: $controlCr;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-top-right-radius: $controlCr;
|
||||||
|
border-bottom-right-radius: $controlCr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -43,6 +43,15 @@ div {
|
|||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.u-space {
|
||||||
|
// Provides a separator space between elements
|
||||||
|
&--right {
|
||||||
|
+ [class*="__"] {
|
||||||
|
margin-left: $interiorMarginLg !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************* BROWSER ELEMENTS */
|
/******************************* BROWSER ELEMENTS */
|
||||||
body.desktop {
|
body.desktop {
|
||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
@ -80,6 +89,13 @@ body.desktop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type=number]::-webkit-inner-spin-button,
|
||||||
|
input[type=number]::-webkit-outer-spin-button {
|
||||||
|
//margin: -1px -5px inherit -5px !important;
|
||||||
|
margin-right: -5px !important;
|
||||||
|
margin-top: -1px !important;
|
||||||
|
}
|
||||||
|
|
||||||
/************************** HTML ENTITIES */
|
/************************** HTML ENTITIES */
|
||||||
a {
|
a {
|
||||||
color: $colorA;
|
color: $colorA;
|
||||||
@ -160,6 +176,48 @@ li {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************************************** HAS */
|
||||||
|
// Local Controls: Controls placed in proximity to or overlaid on components and views
|
||||||
|
body.desktop .has-local-controls {
|
||||||
|
// Provides hover ability to show local controls
|
||||||
|
&:hover [class*="local-controls--hidden"] {
|
||||||
|
transition: opacity 50ms ease-in-out;
|
||||||
|
opacity: 1;
|
||||||
|
pointer-events: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="local-controls--hidden"] {
|
||||||
|
transition: opacity 500ms ease-in-out;
|
||||||
|
opacity: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//[class*="local-controls"] {
|
||||||
|
// // An explicit outer holder for controls. Typically placed in upper right.
|
||||||
|
// //font-size: 0.7rem;
|
||||||
|
// display: flex;
|
||||||
|
// align-items: center;
|
||||||
|
// justify-content: flex-end;
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// &.h-local-controls-overlay-content {
|
||||||
|
// // Imagery controls
|
||||||
|
// $p: $interiorMargin;
|
||||||
|
// position: absolute;
|
||||||
|
// top: $p; right: $p;
|
||||||
|
// z-index: 2;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//.l-btn-set,
|
||||||
|
//.s-button {
|
||||||
|
// &:not(:first-child) {
|
||||||
|
// margin-left: $interiorMargin;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//}
|
||||||
|
|
||||||
/************************** LEGACY */
|
/************************** LEGACY */
|
||||||
|
|
||||||
mct-container {
|
mct-container {
|
||||||
@ -232,21 +290,6 @@ a.disabled {
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-selection {
|
|
||||||
// aka selection = "None". Used in palettes and their menu buttons.
|
|
||||||
$c: red;
|
|
||||||
$s: 48%;
|
|
||||||
$e: 52%;
|
|
||||||
background-image: linear-gradient(-45deg,
|
|
||||||
transparent $s - 5%,
|
|
||||||
$c $s,
|
|
||||||
$c $e,
|
|
||||||
transparent $e + 5%
|
|
||||||
);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: contain;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scrolling,
|
.scrolling,
|
||||||
.scroll {
|
.scroll {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -329,3 +372,8 @@ a.disabled {
|
|||||||
.t-imagery {
|
.t-imagery {
|
||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.t-frame-outer {
|
||||||
|
min-width: 200px;
|
||||||
|
min-height: 200px;
|
||||||
|
}
|
||||||
|
@ -91,7 +91,7 @@
|
|||||||
.icon-refresh { @include glyphBefore($glyph-icon-refresh); }
|
.icon-refresh { @include glyphBefore($glyph-icon-refresh); }
|
||||||
.icon-save { @include glyphBefore($glyph-icon-save); }
|
.icon-save { @include glyphBefore($glyph-icon-save); }
|
||||||
.icon-sine { @include glyphBefore($glyph-icon-sine); }
|
.icon-sine { @include glyphBefore($glyph-icon-sine); }
|
||||||
.icon-T { @include glyphBefore($glyph-icon-T); }
|
.icon-font { @include glyphBefore($glyph-icon-font); }
|
||||||
.icon-thumbs-strip { @include glyphBefore($glyph-icon-thumbs-strip); }
|
.icon-thumbs-strip { @include glyphBefore($glyph-icon-thumbs-strip); }
|
||||||
.icon-two-parts-both { @include glyphBefore($glyph-icon-two-parts-both); }
|
.icon-two-parts-both { @include glyphBefore($glyph-icon-two-parts-both); }
|
||||||
.icon-two-parts-one-only { @include glyphBefore($glyph-icon-two-parts-one-only); }
|
.icon-two-parts-one-only { @include glyphBefore($glyph-icon-two-parts-one-only); }
|
||||||
@ -108,6 +108,7 @@
|
|||||||
.icon-frame-hide { @include glyphBefore($glyph-icon-frame-hide); }
|
.icon-frame-hide { @include glyphBefore($glyph-icon-frame-hide); }
|
||||||
.icon-import { @include glyphBefore($glyph-icon-import); }
|
.icon-import { @include glyphBefore($glyph-icon-import); }
|
||||||
.icon-export { @include glyphBefore($glyph-icon-export); }
|
.icon-export { @include glyphBefore($glyph-icon-export); }
|
||||||
|
.icon-font-size { @include glyphBefore($glyph-icon-font-size); }
|
||||||
.icon-activity { @include glyphBefore($glyph-icon-activity); }
|
.icon-activity { @include glyphBefore($glyph-icon-activity); }
|
||||||
.icon-activity-mode { @include glyphBefore($glyph-icon-activity-mode); }
|
.icon-activity-mode { @include glyphBefore($glyph-icon-activity-mode); }
|
||||||
.icon-autoflow-tabular { @include glyphBefore($glyph-icon-autoflow-tabular); }
|
.icon-autoflow-tabular { @include glyphBefore($glyph-icon-autoflow-tabular); }
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
// VERSION MANUALLY RESTORED FROM VUE-LAYOUT
|
||||||
|
|
||||||
/************************** VISUALS */
|
/************************** VISUALS */
|
||||||
@mixin ancillaryIcon($d, $c) {
|
@mixin ancillaryIcon($d, $c) {
|
||||||
// Used for small icons used in combination with larger icons,
|
// Used for small icons used in combination with larger icons,
|
||||||
@ -53,6 +55,37 @@
|
|||||||
background-size: $bgsize $bgsize;
|
background-size: $bgsize $bgsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin noColor() {
|
||||||
|
// A "no fill/stroke" selection option. Used in palettes.
|
||||||
|
$c: red;
|
||||||
|
$s: 48%;
|
||||||
|
$e: 52%;
|
||||||
|
background-image: linear-gradient(-45deg,
|
||||||
|
transparent $s - 5%,
|
||||||
|
$c $s,
|
||||||
|
$c $e,
|
||||||
|
transparent $e + 5%
|
||||||
|
);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin bgTicks($c: $colorBodyFg, $repeatDir: 'x') {
|
||||||
|
$deg: 90deg;
|
||||||
|
@if ($repeatDir != 'x') {
|
||||||
|
$deg: 0deg;
|
||||||
|
$repeatDir: repeat-y;
|
||||||
|
} @else {
|
||||||
|
$repeatDir: repeat-x;
|
||||||
|
}
|
||||||
|
|
||||||
|
background-image: linear-gradient($deg,
|
||||||
|
$c 1px, transparent 1px,
|
||||||
|
transparent 100%
|
||||||
|
);
|
||||||
|
background-repeat: $repeatDir;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
|
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
|
||||||
@include background-image(linear-gradient(-90deg,
|
@include background-image(linear-gradient(-90deg,
|
||||||
rgba($c, $a) 0%, rgba($c, $a) 50%,
|
rgba($c, $a) 0%, rgba($c, $a) 50%,
|
||||||
@ -63,6 +96,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************** LAYOUT */
|
/************************** LAYOUT */
|
||||||
|
@mixin abs($m: 0) {
|
||||||
|
position: absolute;
|
||||||
|
top: $m; right: $m; bottom: $m; left: $m;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin gridTwoColumn() {
|
@mixin gridTwoColumn() {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-row-gap: 0;
|
grid-row-gap: 0;
|
||||||
@ -110,13 +148,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************** CONTROLS, BUTTONS */
|
/************************** CONTROLS, BUTTONS */
|
||||||
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.5) 0 0px 2px) {
|
@mixin input-base() {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
background: $bg;
|
|
||||||
border: none;
|
border: none;
|
||||||
color: $fg;
|
|
||||||
border-radius: $controlCr;
|
border-radius: $controlCr;
|
||||||
box-shadow: inset $shdw;
|
|
||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
@ -129,6 +164,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.5) 0 0px 2px) {
|
||||||
|
@include input-base();
|
||||||
|
background: $bg;
|
||||||
|
color: $fg;
|
||||||
|
box-shadow: inset $shdw;
|
||||||
|
}
|
||||||
|
|
||||||
@mixin button($bg: $colorBtnBg, $fg: $colorBtnFg, $radius: $controlCr, $shdw: none) {
|
@mixin button($bg: $colorBtnBg, $fg: $colorBtnFg, $radius: $controlCr, $shdw: none) {
|
||||||
background: $bg;
|
background: $bg;
|
||||||
color: $fg;
|
color: $fg;
|
||||||
@ -136,6 +178,63 @@
|
|||||||
box-shadow: $shdw;
|
box-shadow: $shdw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin wrappedInput() {
|
||||||
|
// An input that is wrapped. Optionally includes a __label or icon element.
|
||||||
|
// Based on .c-search.
|
||||||
|
@include nice-input();
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
|
||||||
|
&:before,
|
||||||
|
[class*='__label'] {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Adds an icon. Content defined in class.
|
||||||
|
direction: rtl; // Aligns glyph to right-hand side of container, for transition
|
||||||
|
display: block;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 2px 0; // Prevents clipping
|
||||||
|
transition: width 250ms ease;
|
||||||
|
width: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: inset rgba(black, 0.8) 0 0px 2px;
|
||||||
|
&:before {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--major {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__input,
|
||||||
|
input[type='text'],
|
||||||
|
input[type='search'],
|
||||||
|
input[type='number'] {
|
||||||
|
background: none !important;
|
||||||
|
box-shadow: none !important; // !important needed to override default for [input]
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding-left: 2px !important;
|
||||||
|
padding-right: 2px !important;
|
||||||
|
min-width: 10px; // Must be set to allow input to collapse below browser min
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-active {
|
||||||
|
&:before {
|
||||||
|
padding: 2px 0px;
|
||||||
|
width: 0px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/************************** MATH */
|
/************************** MATH */
|
||||||
@function percentToDecimal($p) {
|
@function percentToDecimal($p) {
|
||||||
@return $p / 100%;
|
@return $p / 100%;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "openmct-symbols-16px",
|
"name": "openmct-symbols-16px",
|
||||||
"lastOpened": 0,
|
"lastOpened": 0,
|
||||||
"created": 1529545133464
|
"created": 1537817705550
|
||||||
},
|
},
|
||||||
"iconSets": [
|
"iconSets": [
|
||||||
{
|
{
|
||||||
@ -525,7 +525,7 @@
|
|||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 102,
|
"order": 149,
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"name": "icon-T",
|
"name": "icon-T",
|
||||||
"id": 84,
|
"id": 84,
|
||||||
@ -660,13 +660,21 @@
|
|||||||
"code": 921672,
|
"code": 921672,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"order": 150,
|
||||||
|
"id": 119,
|
||||||
|
"name": "icon-font-size-alt1",
|
||||||
|
"prevSize": 24,
|
||||||
|
"code": 921673,
|
||||||
|
"tempChar": ""
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"order": 37,
|
"order": 37,
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"name": "icon-activity",
|
"name": "icon-activity",
|
||||||
"id": 32,
|
"id": 32,
|
||||||
"code": 921856,
|
"code": 921856,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 36,
|
"order": 36,
|
||||||
@ -674,7 +682,7 @@
|
|||||||
"name": "icon-activity-mode",
|
"name": "icon-activity-mode",
|
||||||
"id": 31,
|
"id": 31,
|
||||||
"code": 921857,
|
"code": 921857,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 52,
|
"order": 52,
|
||||||
@ -682,7 +690,7 @@
|
|||||||
"name": "icon-autoflow-tabular",
|
"name": "icon-autoflow-tabular",
|
||||||
"id": 47,
|
"id": 47,
|
||||||
"code": 921858,
|
"code": 921858,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 55,
|
"order": 55,
|
||||||
@ -690,7 +698,7 @@
|
|||||||
"name": "icon-clock",
|
"name": "icon-clock",
|
||||||
"id": 50,
|
"id": 50,
|
||||||
"code": 921859,
|
"code": 921859,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 58,
|
"order": 58,
|
||||||
@ -698,7 +706,7 @@
|
|||||||
"name": "icon-database",
|
"name": "icon-database",
|
||||||
"id": 53,
|
"id": 53,
|
||||||
"code": 921860,
|
"code": 921860,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 57,
|
"order": 57,
|
||||||
@ -706,7 +714,7 @@
|
|||||||
"name": "icon-database-query",
|
"name": "icon-database-query",
|
||||||
"id": 52,
|
"id": 52,
|
||||||
"code": 921861,
|
"code": 921861,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 17,
|
"order": 17,
|
||||||
@ -714,7 +722,7 @@
|
|||||||
"name": "icon-dataset",
|
"name": "icon-dataset",
|
||||||
"id": 12,
|
"id": 12,
|
||||||
"code": 921862,
|
"code": 921862,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 22,
|
"order": 22,
|
||||||
@ -722,7 +730,7 @@
|
|||||||
"name": "icon-datatable",
|
"name": "icon-datatable",
|
||||||
"id": 17,
|
"id": 17,
|
||||||
"code": 921863,
|
"code": 921863,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 59,
|
"order": 59,
|
||||||
@ -730,7 +738,7 @@
|
|||||||
"name": "icon-dictionary",
|
"name": "icon-dictionary",
|
||||||
"id": 54,
|
"id": 54,
|
||||||
"code": 921864,
|
"code": 921864,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 62,
|
"order": 62,
|
||||||
@ -738,7 +746,7 @@
|
|||||||
"name": "icon-folder",
|
"name": "icon-folder",
|
||||||
"id": 57,
|
"id": 57,
|
||||||
"code": 921865,
|
"code": 921865,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 66,
|
"order": 66,
|
||||||
@ -746,7 +754,7 @@
|
|||||||
"name": "icon-image",
|
"name": "icon-image",
|
||||||
"id": 61,
|
"id": 61,
|
||||||
"code": 921872,
|
"code": 921872,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 68,
|
"order": 68,
|
||||||
@ -754,7 +762,7 @@
|
|||||||
"name": "icon-layout",
|
"name": "icon-layout",
|
||||||
"id": 63,
|
"id": 63,
|
||||||
"code": 921873,
|
"code": 921873,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 77,
|
"order": 77,
|
||||||
@ -762,7 +770,7 @@
|
|||||||
"name": "icon-object",
|
"name": "icon-object",
|
||||||
"id": 72,
|
"id": 72,
|
||||||
"code": 921874,
|
"code": 921874,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 78,
|
"order": 78,
|
||||||
@ -770,7 +778,7 @@
|
|||||||
"name": "icon-object-unknown",
|
"name": "icon-object-unknown",
|
||||||
"id": 73,
|
"id": 73,
|
||||||
"code": 921875,
|
"code": 921875,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 79,
|
"order": 79,
|
||||||
@ -778,7 +786,7 @@
|
|||||||
"name": "icon-packet",
|
"name": "icon-packet",
|
||||||
"id": 74,
|
"id": 74,
|
||||||
"code": 921876,
|
"code": 921876,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 80,
|
"order": 80,
|
||||||
@ -786,7 +794,7 @@
|
|||||||
"name": "icon-page",
|
"name": "icon-page",
|
||||||
"id": 75,
|
"id": 75,
|
||||||
"code": 921877,
|
"code": 921877,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 135,
|
"order": 135,
|
||||||
@ -794,7 +802,7 @@
|
|||||||
"name": "icon-plot-overlay",
|
"name": "icon-plot-overlay",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 921878,
|
"code": 921878,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 113,
|
"order": 113,
|
||||||
@ -802,7 +810,7 @@
|
|||||||
"name": "icon-plot-stacked",
|
"name": "icon-plot-stacked",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 921879,
|
"code": 921879,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 10,
|
"order": 10,
|
||||||
@ -810,7 +818,7 @@
|
|||||||
"name": "icon-session",
|
"name": "icon-session",
|
||||||
"id": 5,
|
"id": 5,
|
||||||
"code": 921880,
|
"code": 921880,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 24,
|
"order": 24,
|
||||||
@ -818,7 +826,7 @@
|
|||||||
"name": "icon-tabular",
|
"name": "icon-tabular",
|
||||||
"id": 19,
|
"id": 19,
|
||||||
"code": 921881,
|
"code": 921881,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 7,
|
"order": 7,
|
||||||
@ -826,7 +834,7 @@
|
|||||||
"name": "icon-tabular-lad",
|
"name": "icon-tabular-lad",
|
||||||
"id": 2,
|
"id": 2,
|
||||||
"code": 921888,
|
"code": 921888,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 6,
|
"order": 6,
|
||||||
@ -834,7 +842,7 @@
|
|||||||
"name": "icon-tabular-lad-set",
|
"name": "icon-tabular-lad-set",
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"code": 921889,
|
"code": 921889,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 8,
|
"order": 8,
|
||||||
@ -842,7 +850,7 @@
|
|||||||
"name": "icon-tabular-realtime",
|
"name": "icon-tabular-realtime",
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"code": 921890,
|
"code": 921890,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 23,
|
"order": 23,
|
||||||
@ -850,7 +858,7 @@
|
|||||||
"name": "icon-tabular-scrolling",
|
"name": "icon-tabular-scrolling",
|
||||||
"id": 18,
|
"id": 18,
|
||||||
"code": 921891,
|
"code": 921891,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 112,
|
"order": 112,
|
||||||
@ -858,7 +866,7 @@
|
|||||||
"name": "icon-telemetry",
|
"name": "icon-telemetry",
|
||||||
"id": 86,
|
"id": 86,
|
||||||
"code": 921892,
|
"code": 921892,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 90,
|
"order": 90,
|
||||||
@ -866,7 +874,7 @@
|
|||||||
"name": "icon-telemetry-panel",
|
"name": "icon-telemetry-panel",
|
||||||
"id": 85,
|
"id": 85,
|
||||||
"code": 921893,
|
"code": 921893,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 93,
|
"order": 93,
|
||||||
@ -874,15 +882,15 @@
|
|||||||
"name": "icon-timeline",
|
"name": "icon-timeline",
|
||||||
"id": 88,
|
"id": 88,
|
||||||
"code": 921894,
|
"code": 921894,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 116,
|
"order": 116,
|
||||||
"id": 101,
|
"id": 101,
|
||||||
"name": "icon-timer-v1.5",
|
"name": "icon-timer-v15",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 921895,
|
"code": 921895,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 11,
|
"order": 11,
|
||||||
@ -890,7 +898,7 @@
|
|||||||
"name": "icon-topic",
|
"name": "icon-topic",
|
||||||
"id": 6,
|
"id": 6,
|
||||||
"code": 921896,
|
"code": 921896,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 115,
|
"order": 115,
|
||||||
@ -898,7 +906,7 @@
|
|||||||
"name": "icon-box-with-dashed-lines",
|
"name": "icon-box-with-dashed-lines",
|
||||||
"id": 29,
|
"id": 29,
|
||||||
"code": 921897,
|
"code": 921897,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 126,
|
"order": 126,
|
||||||
@ -906,7 +914,7 @@
|
|||||||
"name": "icon-summary-widget",
|
"name": "icon-summary-widget",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 921904,
|
"code": 921904,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"order": 139,
|
"order": 139,
|
||||||
@ -914,13 +922,13 @@
|
|||||||
"name": "icon-notebook",
|
"name": "icon-notebook",
|
||||||
"prevSize": 24,
|
"prevSize": 24,
|
||||||
"code": 921905,
|
"code": 921905,
|
||||||
"tempChar": ""
|
"tempChar": ""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "openmct-symbols-16px",
|
"name": "openmct-symbols-16px",
|
||||||
"importSize": {
|
"importSize": {
|
||||||
"width": 512,
|
"width": 745,
|
||||||
"height": 512
|
"height": 512
|
||||||
},
|
},
|
||||||
"designer": "Charles Hacskaylo",
|
"designer": "Charles Hacskaylo",
|
||||||
@ -2360,7 +2368,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"paths": [
|
"paths": [
|
||||||
"M0 0v256h128v-64h256v704h-192v128h640v-128h-192v-704h256v64h128v-256z"
|
"M800 1024h224l-384-1024h-256l-384 1024h224l84-224h408zM380 608l132-352 132 352z"
|
||||||
],
|
],
|
||||||
"grid": 16,
|
"grid": 16,
|
||||||
"tags": [
|
"tags": [
|
||||||
@ -2368,9 +2376,15 @@
|
|||||||
],
|
],
|
||||||
"defaultCode": 228,
|
"defaultCode": 228,
|
||||||
"id": 84,
|
"id": 84,
|
||||||
"attrs": [],
|
"attrs": [
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"isMulticolor": false,
|
||||||
|
"isMulticolor2": false,
|
||||||
"colorPermutations": {
|
"colorPermutations": {
|
||||||
"1161751207457516161751": []
|
"1161751207457516161751": [
|
||||||
|
{}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -2840,6 +2854,30 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": 119,
|
||||||
|
"paths": [
|
||||||
|
"M1226.4 320h-176l-76.22 203.24 77 205.34 87.22-232.58 90.74 242h-174.44l49.5 132h174.44l57.76 154h154l-264-704z",
|
||||||
|
"M384 0l-384 1024h224l84-224h408l84 224h224l-384-1024zM380 608l132-352 132 352z"
|
||||||
|
],
|
||||||
|
"attrs": [
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
],
|
||||||
|
"width": 1490,
|
||||||
|
"isMulticolor": false,
|
||||||
|
"isMulticolor2": false,
|
||||||
|
"grid": 16,
|
||||||
|
"tags": [
|
||||||
|
"icon-font-size-alt1"
|
||||||
|
],
|
||||||
|
"colorPermutations": {
|
||||||
|
"1161751207457516161751": [
|
||||||
|
{},
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"paths": [
|
"paths": [
|
||||||
"M576 64h-256l320 320h-290.256c-44.264-76.516-126.99-128-221.744-128h-128v512h128c94.754 0 177.48-51.484 221.744-128h290.256l-320 320h256l448-448-448-448z"
|
"M576 64h-256l320 320h-290.256c-44.264-76.516-126.99-128-221.744-128h-128v512h128c94.754 0 177.48-51.484 221.744-128h290.256l-320 320h256l448-448-448-448z"
|
||||||
@ -3740,7 +3778,9 @@
|
|||||||
"classSelector": ".ui-symbol",
|
"classSelector": ".ui-symbol",
|
||||||
"showMetrics": true,
|
"showMetrics": true,
|
||||||
"showMetadata": true,
|
"showMetadata": true,
|
||||||
"embed": false
|
"embed": false,
|
||||||
|
"noie8": true,
|
||||||
|
"ie7": false
|
||||||
},
|
},
|
||||||
"imagePref": {
|
"imagePref": {
|
||||||
"prefix": "icon-",
|
"prefix": "icon-",
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
<glyph unicode="󡀩" glyph-name="icon-refresh" d="M960 528v432l-164.8-164.8c-79.8 65.2-178.8 100.8-283.2 100.8-119.6 0-232.2-46.6-316.8-131.2s-131.2-197.2-131.2-316.8 46.6-232.2 131.2-316.8c84.6-84.6 197.2-131.2 316.8-131.2s232.2 46.6 316.8 131.2c69.4 69.4 113.2 157.4 126.6 252.8h-130c-29.8-145.8-159-256-313.6-256-176.4 0-320 143.6-320 320s143.8 320 320.2 320c72 0 138.4-23.8 192-64l-176-176h432z" />
|
<glyph unicode="󡀩" glyph-name="icon-refresh" d="M960 528v432l-164.8-164.8c-79.8 65.2-178.8 100.8-283.2 100.8-119.6 0-232.2-46.6-316.8-131.2s-131.2-197.2-131.2-316.8 46.6-232.2 131.2-316.8c84.6-84.6 197.2-131.2 316.8-131.2s232.2 46.6 316.8 131.2c69.4 69.4 113.2 157.4 126.6 252.8h-130c-29.8-145.8-159-256-313.6-256-176.4 0-320 143.6-320 320s143.8 320 320.2 320c72 0 138.4-23.8 192-64l-176-176h432z" />
|
||||||
<glyph unicode="󡀰" glyph-name="icon-save" d="M192.2 384c-0.2 0-0.2 0 0 0l-0.2-448h640v447.8c0 0 0 0-0.2 0.2h-639.6zM978.8 749.2l-165.4 165.4c-25 25-74.2 45.4-109.4 45.4h-576c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128v448c0 35.2 28.8 64 64 64h640c35.2 0 64-28.8 64-64v-448c70.4 0 128 57.6 128 128v576c0 35.2-20.4 84.4-45.2 109.2zM704 704c0-35.2-28.8-64-64-64h-448c-35.2 0-64 28.8-64 64v192h320v-192h128v192h128v-192z" />
|
<glyph unicode="󡀰" glyph-name="icon-save" d="M192.2 384c-0.2 0-0.2 0 0 0l-0.2-448h640v447.8c0 0 0 0-0.2 0.2h-639.6zM978.8 749.2l-165.4 165.4c-25 25-74.2 45.4-109.4 45.4h-576c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128v448c0 35.2 28.8 64 64 64h640c35.2 0 64-28.8 64-64v-448c70.4 0 128 57.6 128 128v576c0 35.2-20.4 84.4-45.2 109.2zM704 704c0-35.2-28.8-64-64-64h-448c-35.2 0-64 28.8-64 64v192h320v-192h128v192h128v-192z" />
|
||||||
<glyph unicode="󡀱" glyph-name="icon-sine" d="M1022.294 448c-1.746 7.196-3.476 14.452-5.186 21.786-20.036 85.992-53.302 208.976-98 306.538-22.42 48.938-45.298 86.556-69.946 115.006-48.454 55.93-98.176 67.67-131.356 67.67s-82.902-11.74-131.356-67.672c-24.648-28.45-47.528-66.068-69.948-115.006-44.696-97.558-77.962-220.544-98-306.538-21.646-92.898-46.444-175.138-71.71-237.836-16.308-40.46-30.222-66.358-40.6-82.604-10.378 16.246-24.292 42.142-40.6 82.604-23.272 57.75-46.144 132.088-66.524 216.052h-197.362c1.746-7.196 3.476-14.452 5.186-21.786 20.036-85.992 53.302-208.976 98-306.538 22.42-48.938 45.298-86.556 69.946-115.006 48.454-55.932 98.176-67.672 131.356-67.672s82.902 11.74 131.356 67.672c24.648 28.45 47.528 66.068 69.948 115.006 44.696 97.558 77.962 220.544 98 306.538 21.646 92.898 46.444 175.138 71.71 237.836 16.308 40.46 30.222 66.358 40.6 82.604 10.378-16.246 24.292-42.142 40.6-82.604 23.274-57.748 46.146-132.086 66.526-216.050h197.36z" />
|
<glyph unicode="󡀱" glyph-name="icon-sine" d="M1022.294 448c-1.746 7.196-3.476 14.452-5.186 21.786-20.036 85.992-53.302 208.976-98 306.538-22.42 48.938-45.298 86.556-69.946 115.006-48.454 55.93-98.176 67.67-131.356 67.67s-82.902-11.74-131.356-67.672c-24.648-28.45-47.528-66.068-69.948-115.006-44.696-97.558-77.962-220.544-98-306.538-21.646-92.898-46.444-175.138-71.71-237.836-16.308-40.46-30.222-66.358-40.6-82.604-10.378 16.246-24.292 42.142-40.6 82.604-23.272 57.75-46.144 132.088-66.524 216.052h-197.362c1.746-7.196 3.476-14.452 5.186-21.786 20.036-85.992 53.302-208.976 98-306.538 22.42-48.938 45.298-86.556 69.946-115.006 48.454-55.932 98.176-67.672 131.356-67.672s82.902 11.74 131.356 67.672c24.648 28.45 47.528 66.068 69.948 115.006 44.696 97.558 77.962 220.544 98 306.538 21.646 92.898 46.444 175.138 71.71 237.836 16.308 40.46 30.222 66.358 40.6 82.604 10.378-16.246 24.292-42.142 40.6-82.604 23.274-57.748 46.146-132.086 66.526-216.050h197.36z" />
|
||||||
<glyph unicode="󡀲" glyph-name="icon-T" d="M0 960v-256h128v64h256v-704h-192v-128h640v128h-192v704h256v-64h128v256z" />
|
<glyph unicode="󡀲" glyph-name="icon-T" d="M800-64h224l-384 1024h-256l-384-1024h224l84 224h408zM380 352l132 352 132-352z" />
|
||||||
<glyph unicode="󡀳" glyph-name="icon-thumbs-strip" d="M448 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM448 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320z" />
|
<glyph unicode="󡀳" glyph-name="icon-thumbs-strip" d="M448 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 578c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM448 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320zM1024 2c0-35.2-28.8-64-64-64h-320c-35.2 0-64 28.8-64 64v320c0 35.2 28.8 64 64 64h320c35.2 0 64-28.8 64-64v-320z" />
|
||||||
<glyph unicode="󡀴" glyph-name="icon-two-parts-both" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM128 832h320v-768h-320v768zM896 64h-320v768h320v-768z" />
|
<glyph unicode="󡀴" glyph-name="icon-two-parts-both" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM128 832h320v-768h-320v768zM896 64h-320v768h320v-768z" />
|
||||||
<glyph unicode="󡀵" glyph-name="icon-two-parts-one-only" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM896 64h-320v768h320v-768z" />
|
<glyph unicode="󡀵" glyph-name="icon-two-parts-one-only" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM896 64h-320v768h320v-768z" />
|
||||||
@ -88,6 +88,7 @@
|
|||||||
<glyph unicode="󡁆" glyph-name="icon-frame-hide" d="M128 770h420l104 128h-652v-802.4l128 157.4zM896 130h-420l-104-128h652v802.4l-128-157.4zM832 962l-832-1024h192l832 1024zM392 578l104 128h-304v-128z" />
|
<glyph unicode="󡁆" glyph-name="icon-frame-hide" d="M128 770h420l104 128h-652v-802.4l128 157.4zM896 130h-420l-104-128h652v802.4l-128-157.4zM832 962l-832-1024h192l832 1024zM392 578l104 128h-304v-128z" />
|
||||||
<glyph unicode="󡁇" glyph-name="icon-import" d="M832 767.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 256v-192l384 384-384 384v-192h-192v-384z" />
|
<glyph unicode="󡁇" glyph-name="icon-import" d="M832 767.6v-639.4c0-0.2-0.2-0.2-0.4-0.4h-319.6v-192h320c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192h-320v-192h319.6c0.2 0 0.4-0.2 0.4-0.4zM192 256v-192l384 384-384 384v-192h-192v-384z" />
|
||||||
<glyph unicode="󡁈" glyph-name="icon-export" d="M192 128.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 448l-384 384v-192h-192v-384h192v-192l384 384z" />
|
<glyph unicode="󡁈" glyph-name="icon-export" d="M192 128.34v639.32l0.34 0.34h319.66v192h-320c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h320v192h-319.66zM1024 448l-384 384v-192h-192v-384h192v-192l384 384z" />
|
||||||
|
<glyph unicode="󡁉" glyph-name="icon-font-size-alt1" horiz-adv-x="1490" d="M1226.4 640h-176l-76.22-203.24 77-205.34 87.22 232.58 90.74-242h-174.44l49.5-132h174.44l57.76-154h154l-264 704zM384 960l-384-1024h224l84 224h408l84-224h224l-384 1024zM380 352l132 352 132-352z" />
|
||||||
<glyph unicode="󡄀" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
<glyph unicode="󡄀" glyph-name="icon-activity" d="M576 896h-256l320-320h-290.256c-44.264 76.516-126.99 128-221.744 128h-128v-512h128c94.754 0 177.48 51.484 221.744 128h290.256l-320-320h256l448 448-448 448z" />
|
||||||
<glyph unicode="󡄁" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
|
<glyph unicode="󡄁" glyph-name="icon-activity-mode" d="M512 960c-214.866 0-398.786-132.372-474.744-320h90.744c56.86 0 107.938-24.724 143.094-64h240.906l-192 192h256l320-320-320-320h-256l192 192h-240.906c-35.156-39.276-86.234-64-143.094-64h-90.744c75.958-187.628 259.878-320 474.744-320 282.77 0 512 229.23 512 512s-229.23 512-512 512z" />
|
||||||
<glyph unicode="󡄂" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
<glyph unicode="󡄂" glyph-name="icon-autoflow-tabular" d="M192 960c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h64v1024h-64zM384 960h256v-1024h-256v1024zM832 960h-64v-704h256v512c0 105.6-86.4 192-192 192z" />
|
||||||
@ -115,7 +116,7 @@
|
|||||||
<glyph unicode="󡄤" glyph-name="icon-telemetry" d="M32 328.34c14.28 5.62 54.44 47.54 92.96 146 42.46 108.38 116.32 237.66 227.040 237.66 52.4 0 101.42-29.16 145.7-86.68 37.34-48.5 64.84-108.92 81.34-151.080 38.52-98.38 78.68-140.3 92.96-146 14.28 5.62 54.44 47.54 92.96 146 37.4 95.5 99.14 207.14 188.94 232.46-90.462 152.598-254.314 253.3-441.686 253.3-0.075 0-0.15 0-0.226 0-282.748 0-511.988-229.24-511.988-512 0-0.032 0-0.070 0-0.108 0-35.719 3.641-70.587 10.572-104.255 8.968-7.457 16.648-13.417 21.428-15.297zM992 567.66c-14.28-5.62-54.44-47.52-92.96-146-42.46-108.38-116.32-237.66-227.040-237.66-52.4 0-101.42 29.16-145.7 86.68-37.34 48.5-64.84 108.92-81.34 151.080-38.52 98.38-78.68 140.3-92.96 146-14.28-5.62-54.44-47.52-92.96-146-37.4-95.5-99.14-207.14-188.94-232.46 90.462-152.598 254.314-253.3 441.686-253.3 0.075 0 0.15 0 0.226 0 282.748 0 511.988 229.24 511.988 512 0 0.032 0 0.070 0 0.108 0 35.719-3.641 70.587-10.572 104.255-8.968 7.457-16.648 13.417-21.428 15.297z" />
|
<glyph unicode="󡄤" glyph-name="icon-telemetry" d="M32 328.34c14.28 5.62 54.44 47.54 92.96 146 42.46 108.38 116.32 237.66 227.040 237.66 52.4 0 101.42-29.16 145.7-86.68 37.34-48.5 64.84-108.92 81.34-151.080 38.52-98.38 78.68-140.3 92.96-146 14.28 5.62 54.44 47.54 92.96 146 37.4 95.5 99.14 207.14 188.94 232.46-90.462 152.598-254.314 253.3-441.686 253.3-0.075 0-0.15 0-0.226 0-282.748 0-511.988-229.24-511.988-512 0-0.032 0-0.070 0-0.108 0-35.719 3.641-70.587 10.572-104.255 8.968-7.457 16.648-13.417 21.428-15.297zM992 567.66c-14.28-5.62-54.44-47.52-92.96-146-42.46-108.38-116.32-237.66-227.040-237.66-52.4 0-101.42 29.16-145.7 86.68-37.34 48.5-64.84 108.92-81.34 151.080-38.52 98.38-78.68 140.3-92.96 146-14.28-5.62-54.44-47.52-92.96-146-37.4-95.5-99.14-207.14-188.94-232.46 90.462-152.598 254.314-253.3 441.686-253.3 0.075 0 0.15 0 0.226 0 282.748 0 511.988 229.24 511.988 512 0 0.032 0 0.070 0 0.108 0 35.719-3.641 70.587-10.572 104.255-8.968 7.457-16.648 13.417-21.428 15.297z" />
|
||||||
<glyph unicode="󡄥" glyph-name="icon-telemetry-panel" d="M169.2 512c14 56.4 33 122 56.6 176.8 15.4 35.8 31.2 63.2 48.2 84 18.4 22.4 49 49.2 91 49.2s72.6-26.8 91-49.2c17-20.6 32.6-48.2 48.2-84 23.6-54.8 42.8-120.4 56.6-176.8h461.2v256c0 105.6-86.4 192-192 192h-640c-105.6 0-192-86.4-192-192v-256h171.2zM718.6 384h-127.2c25-93.4 48.4-144.4 63.6-168.6 15.2 24.2 38.6 75.2 63.6 168.6zM301.4 512h127.2c-25 93.4-48.4 144.4-63.6 168.6-15.2-24.2-38.6-75.2-63.6-168.6zM850.8 384c-14-56.4-33-122-56.6-176.8-15.4-35.8-31.2-63.2-48.2-84-18.4-22.4-49-49.2-91-49.2s-72.6 26.8-91 49.2c-17 20.6-32.6 48.2-48.2 84-23.6 54.8-42.8 120.4-56.6 176.8h-461.2v-256c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v256h-171.2z" />
|
<glyph unicode="󡄥" glyph-name="icon-telemetry-panel" d="M169.2 512c14 56.4 33 122 56.6 176.8 15.4 35.8 31.2 63.2 48.2 84 18.4 22.4 49 49.2 91 49.2s72.6-26.8 91-49.2c17-20.6 32.6-48.2 48.2-84 23.6-54.8 42.8-120.4 56.6-176.8h461.2v256c0 105.6-86.4 192-192 192h-640c-105.6 0-192-86.4-192-192v-256h171.2zM718.6 384h-127.2c25-93.4 48.4-144.4 63.6-168.6 15.2 24.2 38.6 75.2 63.6 168.6zM301.4 512h127.2c-25 93.4-48.4 144.4-63.6 168.6-15.2-24.2-38.6-75.2-63.6-168.6zM850.8 384c-14-56.4-33-122-56.6-176.8-15.4-35.8-31.2-63.2-48.2-84-18.4-22.4-49-49.2-91-49.2s-72.6 26.8-91 49.2c-17 20.6-32.6 48.2-48.2 84-23.6 54.8-42.8 120.4-56.6 176.8h-461.2v-256c0-105.6 86.4-192 192-192h640c105.6 0 192 86.4 192 192v256h-171.2z" />
|
||||||
<glyph unicode="󡄦" glyph-name="icon-timeline" d="M256 704h384v-128h-384v128zM384 512h384v-128h-384v128zM320 320h384v-128h-384v128zM832 960h-128v-192h127.6c0.2 0 0.2-0.2 0.4-0.4v-639.4c0-0.2-0.2-0.2-0.4-0.4h-127.6v-192h128c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192zM192 128.4v639.2c0 0.2 0.2 0.2 0.4 0.4h127.6v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192h-127.6c-0.2 0-0.4 0.2-0.4 0.4z" />
|
<glyph unicode="󡄦" glyph-name="icon-timeline" d="M256 704h384v-128h-384v128zM384 512h384v-128h-384v128zM320 320h384v-128h-384v128zM832 960h-128v-192h127.6c0.2 0 0.2-0.2 0.4-0.4v-639.4c0-0.2-0.2-0.2-0.4-0.4h-127.6v-192h128c105.6 0 192 86.4 192 192v640.2c0 105.6-86.4 192-192 192zM192 128.4v639.2c0 0.2 0.2 0.2 0.4 0.4h127.6v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192h-127.6c-0.2 0-0.4 0.2-0.4 0.4z" />
|
||||||
<glyph unicode="󡄧" glyph-name="icon-timer-v1.5" horiz-adv-x="896" d="M576 813.4v82.58c0 35.346-28.654 64-64 64h-128c-35.346 0-64-28.654-64-64v-82.58c-185.040-55.080-320-226.48-320-429.42 0-247.42 200.58-448 448-448s448 200.58 448 448c0 202.96-135 374.4-320 429.42zM468 363.98l-263.76-211c-57.105 59.935-92.24 141.251-92.24 230.772 0 0.080 0 0.16 0 0.24 0 185.268 150.72 335.988 336 335.988 6.72 0 13.38-0.22 20-0.62v-355.38z" />
|
<glyph unicode="󡄧" glyph-name="icon-timer-v15" horiz-adv-x="896" d="M576 813.4v82.58c0 35.346-28.654 64-64 64h-128c-35.346 0-64-28.654-64-64v-82.58c-185.040-55.080-320-226.48-320-429.42 0-247.42 200.58-448 448-448s448 200.58 448 448c0 202.96-135 374.4-320 429.42zM468 363.98l-263.76-211c-57.105 59.935-92.24 141.251-92.24 230.772 0 0.080 0 0.16 0 0.24 0 185.268 150.72 335.988 336 335.988 6.72 0 13.38-0.22 20-0.62v-355.38z" />
|
||||||
<glyph unicode="󡄨" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
|
<glyph unicode="󡄨" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" />
|
||||||
<glyph unicode="󡄩" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" />
|
<glyph unicode="󡄩" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" />
|
||||||
<glyph unicode="󡄰" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" />
|
<glyph unicode="󡄰" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" />
|
||||||
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Binary file not shown.
Binary file not shown.
@ -64,7 +64,7 @@
|
|||||||
@import "../styles/items/item";
|
@import "../styles/items/item";
|
||||||
@import "../styles/mobile/item";
|
@import "../styles/mobile/item";
|
||||||
@import "../styles/table";
|
@import "../styles/table";
|
||||||
@import "../styles/notebook/notebook";
|
//@import "../styles/notebook/notebook";
|
||||||
//
|
//
|
||||||
//!********************************* TO BE MOVED *!
|
//!********************************* TO BE MOVED *!
|
||||||
@import "../styles/autoflow";
|
@import "../styles/autoflow";
|
||||||
@ -76,3 +76,4 @@
|
|||||||
//@import "../styles/app-start";
|
//@import "../styles/app-start";
|
||||||
|
|
||||||
@import "../styles/conductor/time-conductor-snow";
|
@import "../styles/conductor/time-conductor-snow";
|
||||||
|
//@import "../styles/notebook/notebook-snow";
|
385
src/styles-new/notebook.scss
Normal file
385
src/styles-new/notebook.scss
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
/*********************************************** NOTEBOOK */
|
||||||
|
@import "sass-base.scss";
|
||||||
|
|
||||||
|
|
||||||
|
.c-notebook {
|
||||||
|
//@include test(orange);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 0px;
|
||||||
|
|
||||||
|
> [class*="__"] + [class*="__"] {
|
||||||
|
margin-top: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head,
|
||||||
|
&__controls,
|
||||||
|
&__drag-area,
|
||||||
|
&__entries {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head,
|
||||||
|
&__drag-area,
|
||||||
|
&__controls {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__head {
|
||||||
|
[class*="__"] + [class*="__"] {
|
||||||
|
margin-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__search {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__drag-area {
|
||||||
|
background: rgba($colorKey, 0.1);
|
||||||
|
border: 1px dashed rgba($colorKey, 0.7);
|
||||||
|
border-radius: $controlCr;
|
||||||
|
color: rgba($colorBodyFg, 0.7);
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
margin-right: 7px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="__label"] {
|
||||||
|
font-style: italic;
|
||||||
|
@include ellipsize();
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba($colorKey, 0.2);
|
||||||
|
color: $colorBodyFg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.drag-active,
|
||||||
|
&.is-active {
|
||||||
|
// Not currently working
|
||||||
|
border-color: $colorKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.mobile & {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__entries {
|
||||||
|
flex-direction: column;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
padding-right: $interiorMarginSm;
|
||||||
|
overflow-x: hidden;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
[class*="__entry"] + [class*="__entry"] {
|
||||||
|
margin-top: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** ENTRIES */
|
||||||
|
.c-ne {
|
||||||
|
// A Notebook entry
|
||||||
|
$p: $interiorMarginSm;
|
||||||
|
@include discreteItem();
|
||||||
|
display: flex;
|
||||||
|
//flex-wrap: wrap;
|
||||||
|
padding: $interiorMarginSm $interiorMarginSm $interiorMarginSm $interiorMargin;
|
||||||
|
|
||||||
|
&__time,
|
||||||
|
&__text,
|
||||||
|
&__local-controls {
|
||||||
|
padding-top: $p;
|
||||||
|
padding-bottom: $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__time,
|
||||||
|
&__embed__time {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__time-and-content {
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__time {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
min-width: 130px;
|
||||||
|
margin-right: $interiorMarginLg;
|
||||||
|
|
||||||
|
* {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
|
||||||
|
> [class*="__"] + [class*="__"] {
|
||||||
|
margin-top: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__text {
|
||||||
|
min-height: 24px; // Needed in Firefox when field is blank
|
||||||
|
white-space: pre-wrap;
|
||||||
|
|
||||||
|
&.is-blank-notebook-entry {
|
||||||
|
&:not(:focus):before {
|
||||||
|
content: 'Blank entry';
|
||||||
|
font-style: italic;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__embeds {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
> [class*="__embed"] {
|
||||||
|
margin: 0 $interiorMarginSm $interiorMarginSm 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** EMBEDS */
|
||||||
|
@mixin snapThumb() {
|
||||||
|
// LEGACY: TODO: refactor when .snap-thumb in New Entry dialog is refactored
|
||||||
|
$d: 50px;
|
||||||
|
border: 1px solid $colorInteriorBorder;
|
||||||
|
cursor: pointer;
|
||||||
|
width: $d;
|
||||||
|
height: $d;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.snap-thumb {
|
||||||
|
// LEGACY,
|
||||||
|
@include snapThumb();
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-ne__embed {
|
||||||
|
@include discreteItemInnerElem();
|
||||||
|
display: inline-flex;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
padding: $interiorMargin;
|
||||||
|
|
||||||
|
[class*="__"] + [class*="__"] {
|
||||||
|
margin-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__info {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $colorKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name,
|
||||||
|
&__link {
|
||||||
|
// Holds __link and __context-available
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__link {
|
||||||
|
&:before {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.85em;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__context-available {
|
||||||
|
font-size: 0.7em;
|
||||||
|
margin-left: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__snap-thumb {
|
||||||
|
@include snapThumb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/****************************** SNAPSHOTTING */
|
||||||
|
// LEGACY: TODO: refactor these names
|
||||||
|
.t-contents,
|
||||||
|
.snap-annotation {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.s-status-taking-snapshot,
|
||||||
|
.overlay.snapshot {
|
||||||
|
// Handle overflow-y issues with tables and html2canvas
|
||||||
|
.l-sticky-headers .l-tabular-body { overflow: auto; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** PAINTERRO OVERRIDES */
|
||||||
|
.annotation-dialog .abs.editor {
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#snap-annotation {
|
||||||
|
$m: $interiorMargin;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: absolute;
|
||||||
|
top: $m; right: 0; bottom: $m; left: 0; // LEGACY, deal with .editor border-radius clipping stuff
|
||||||
|
}
|
||||||
|
|
||||||
|
#snap-annotation-wrapper,
|
||||||
|
#snap-annotation-bar {
|
||||||
|
position: relative;
|
||||||
|
top: auto; right: auto; bottom: auto; left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#snap-annotation-wrapper {
|
||||||
|
background: rgba($colorBodyFg, 0.1);
|
||||||
|
border: 1px solid $colorInteriorBorder;
|
||||||
|
order: 2;
|
||||||
|
flex: 10 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#snap-annotation-bar {
|
||||||
|
// Holds tool buttons, color selectors, etc.
|
||||||
|
$h: 22px;
|
||||||
|
$fs: 0.8rem;
|
||||||
|
|
||||||
|
order: 1;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
height: auto;
|
||||||
|
background-color: transparent !important;
|
||||||
|
margin-bottom: $interiorMargin;
|
||||||
|
|
||||||
|
> div > span {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: $fs;
|
||||||
|
}
|
||||||
|
|
||||||
|
> div,
|
||||||
|
> div > span,
|
||||||
|
.ptro-icon-btn,
|
||||||
|
.ptro-named-btn,
|
||||||
|
.ptro-color-btn,
|
||||||
|
.ptro-bordered-btn,
|
||||||
|
.ptro-tool-ctl-name,
|
||||||
|
.ptro-color-btn,
|
||||||
|
.tool-controls,
|
||||||
|
.ptro-input {
|
||||||
|
// Lot of resets for crappy CSS in Painterro
|
||||||
|
&:first-child {
|
||||||
|
margin-left: 0 !important;
|
||||||
|
}
|
||||||
|
display: inline-block;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: $fs !important;
|
||||||
|
height: $h !important;
|
||||||
|
margin: 0 0 0 5px;
|
||||||
|
position: relative;
|
||||||
|
width: auto !important;
|
||||||
|
line-height: $h !important;
|
||||||
|
top: auto;
|
||||||
|
right: auto;
|
||||||
|
bottom: auto;
|
||||||
|
left: auto;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ptro-tool-ctl-name {
|
||||||
|
border-radius: 0;
|
||||||
|
background: none;
|
||||||
|
top: auto;
|
||||||
|
font-family: inherit;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ptro-color-btn {
|
||||||
|
width: $h !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ptro-color-control,
|
||||||
|
.ptro-icon-btn,
|
||||||
|
.ptro-named-btn {
|
||||||
|
// Buttons in toolbar. Why the f* they're named like this is a mystery
|
||||||
|
background-color: $colorBtnBg;
|
||||||
|
color: $colorBtnFg;
|
||||||
|
padding: 0 $interiorMargin;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $colorBtnBgHov;
|
||||||
|
color: $colorBtnFgHov;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: contents;
|
||||||
|
font-size: $fs * 1.2;
|
||||||
|
line-height: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ptro-color-active-control {
|
||||||
|
background: $colorBtnMajorBg !important;
|
||||||
|
color: $colorBtnMajorFg !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ptro-info,
|
||||||
|
.ptro-btn-color-checkers-bar,
|
||||||
|
*[title="Font name"],
|
||||||
|
*[title="Stroke color"],
|
||||||
|
*[title="Stroke width"],
|
||||||
|
*[data-id="fontName"],
|
||||||
|
*[data-id="fontStrokeSize"],
|
||||||
|
*[data-id="stroke"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************** MOBILE */
|
||||||
|
body.mobile {
|
||||||
|
.c-notebook__drag-area { display: none; }
|
||||||
|
.c-notebook__entry {
|
||||||
|
[class*="local-controls"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.phone.portrait {
|
||||||
|
.c-notebook__head,
|
||||||
|
.c-notebook__entry {
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
> [class*="__"] + [class*="__"] {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-top: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-notebook__entry {
|
||||||
|
[class*="text"] {
|
||||||
|
min-height: 0;
|
||||||
|
padding: 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,30 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-create-button--w">
|
<div class="c-ctrl-wrapper">
|
||||||
<div class="c-create-button c-menu-button c-button--major icon-plus"
|
<div class="c-create-button c-button--menu c-button--major icon-plus"
|
||||||
@click="toggleCreateMenu">
|
@click="toggleCreateMenu">
|
||||||
Create
|
<span class="c-button__label">Create</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-create-menu c-super-menu"
|
<div class="c-create-menu c-super-menu"
|
||||||
v-if="showCreateMenu">
|
v-if="showCreateMenu">
|
||||||
<div class="c-super-menu__menu">
|
<div class="c-super-menu__menu">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="item in createMenuItems"
|
<li v-for="(item, index) in items"
|
||||||
|
:key="index"
|
||||||
:class="item.class"
|
:class="item.class"
|
||||||
:title="item.title"
|
:title="item.title"
|
||||||
@mouseover="showItemDescription">
|
@mouseover="showItemDescription(item)">
|
||||||
{{ item.name }}
|
{{ item.name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-super-menu__item-description">
|
<div class="c-super-menu__item-description">
|
||||||
<div class="l-item-description__icon bg-icon-plot-stacked"></div>
|
<div :class="['l-item-description__icon', 'bg-' + selectedMenuItem.class]"></div>
|
||||||
<div class="l-item-description__name">Name</div>
|
<div class="l-item-description__name">{{selectedMenuItem.name}}</div>
|
||||||
<div class="l-item-description__description">
|
<div class="l-item-description__description">{{selectedMenuItem.title}}</div>
|
||||||
A timer that counts up or down to a datetime.
|
|
||||||
Timers can be started, stopped and reset whenever needed,
|
|
||||||
and support a variety of display formats.
|
|
||||||
Each Timer displays the same value to all users.
|
|
||||||
Timers can be added to Display Layouts.</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -35,14 +31,14 @@
|
|||||||
|
|
||||||
.c-create-button,
|
.c-create-button,
|
||||||
.c-create-menu {
|
.c-create-menu {
|
||||||
&--w {
|
|
||||||
// Wrapper for Create button and menu
|
|
||||||
overflow: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c-create-button .c-button__label {
|
||||||
|
text-transform: $createBtnTextTransform;
|
||||||
|
}
|
||||||
|
|
||||||
.c-create-menu {
|
.c-create-menu {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
@ -61,6 +57,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
props: {
|
props: {
|
||||||
showCreateMenu: {
|
showCreateMenu: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@ -71,27 +68,30 @@
|
|||||||
toggleCreateMenu: function () {
|
toggleCreateMenu: function () {
|
||||||
this.showCreateMenu = !this.showCreateMenu;
|
this.showCreateMenu = !this.showCreateMenu;
|
||||||
},
|
},
|
||||||
|
showItemDescription: function (menuItem) {
|
||||||
|
this.selectedMenuItem = menuItem;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
|
let items = [];
|
||||||
|
|
||||||
|
this.openmct.types.listKeys().forEach(key => {
|
||||||
|
let menuItem = openmct.types.get(key).definition;
|
||||||
|
|
||||||
|
if (menuItem.creatable) {
|
||||||
|
let menuItemTemplate = {
|
||||||
|
name: menuItem.name,
|
||||||
|
class: menuItem.cssClass,
|
||||||
|
title: menuItem.description
|
||||||
|
};
|
||||||
|
|
||||||
|
items.push(menuItemTemplate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createMenuItems: [
|
items: items,
|
||||||
{ name: 'Folder', class: 'icon-folder', title: 'Details will go here' },
|
selectedMenuItem: {}
|
||||||
{ name: 'Display Layout', class: 'icon-layout', title: 'Details will go here' },
|
|
||||||
{ name: 'Fixed Position Display', class: 'icon-box-with-dashed-lines', title: 'Details will go here' },
|
|
||||||
{ name: 'Overlay Plot', class: 'icon-plot-overlay', title: 'Details will go here' },
|
|
||||||
{ name: 'Stacked Plot', class: 'icon-plot-stacked', title: 'Details will go here' },
|
|
||||||
{ name: 'Telemetry Table', class: 'icon-tabular-realtime', title: 'Details will go here' },
|
|
||||||
{ name: 'Clock', class: 'icon-clock', title: 'Details will go here' },
|
|
||||||
{ name: 'Timer', class: 'icon-timer', title: 'Details will go here' },
|
|
||||||
{ name: 'Web Page', class: 'icon-page', title: 'Details will go here' },
|
|
||||||
{ name: 'Event Message Generator', class: 'icon-folder-new', title: 'Details will go here' },
|
|
||||||
{ name: 'Hyperlink', class: 'icon-chain-links', title: 'Details will go here' },
|
|
||||||
{ name: 'Notebook', class: 'icon-notebook', title: 'Details will go here' },
|
|
||||||
{ name: 'State Generator', class: 'icon-telemetry', title: 'Details will go here' },
|
|
||||||
{ name: 'Sine Wave Generator', class: 'icon-telemetry', title: 'Details will go here' },
|
|
||||||
{ name: 'Example Imagery', class: 'icon-image', title: 'Details will go here' },
|
|
||||||
{ name: 'Summary Widget', class: 'icon-summary-widget', title: 'Details will go here' }
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
168
src/ui/components/controls/checkboxCustom.vue
Normal file
168
src/ui/components/controls/checkboxCustom.vue
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-custom-checkbox">
|
||||||
|
<input type="checkbox"
|
||||||
|
:id="id"
|
||||||
|
:name="name"
|
||||||
|
:value="value"
|
||||||
|
:required="required"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="onChange"
|
||||||
|
:checked="state">
|
||||||
|
<label :for="id">
|
||||||
|
<div class="c-custom-checkbox__box"></div>
|
||||||
|
<div class="c-custom-checkbox__label-text">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
.c-custom-checkbox {
|
||||||
|
$d: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
label {
|
||||||
|
@include userSelectNone();
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__box {
|
||||||
|
@include nice-input();
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: $d;
|
||||||
|
width: $d;
|
||||||
|
height: $d;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&:checked + label > .c-custom-checkbox__box {
|
||||||
|
background: $colorKey;
|
||||||
|
&:before {
|
||||||
|
color: $colorKeyFg;
|
||||||
|
content: $glyph-icon-check;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled) + label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled + label {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/*
|
||||||
|
Custom checkbox control. Use just like a checkbox in HTML, except label string is passed within tag.
|
||||||
|
Supports value, true-value, false-value, checked and disabled attributes.
|
||||||
|
Example usage:
|
||||||
|
<checkbox checked>Enable markers</checkbox>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
model: {
|
||||||
|
prop: 'modelValue',
|
||||||
|
event: 'input'
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: function () {
|
||||||
|
return 'checkbox-id-' + this._uid;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
checked: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
model: {}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
state() {
|
||||||
|
if (this.modelValue === undefined) {
|
||||||
|
return this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(this.modelValue)) {
|
||||||
|
return this.modelValue.indexOf(this.value) > -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!this.modelValue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onChange() {
|
||||||
|
this.toggle();
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
let value;
|
||||||
|
|
||||||
|
if (Array.isArray(this.modelValue)) {
|
||||||
|
value = this.modelValue.slice(0);
|
||||||
|
|
||||||
|
if (this.state) {
|
||||||
|
value.splice(value.indexOf(this.value), 1);
|
||||||
|
} else {
|
||||||
|
value.push(this.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = !this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('input', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
checked(newValue) {
|
||||||
|
if (newValue !== this.state) {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
if (this.checked && !this.state) {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
51
src/ui/components/controls/labeledNumberInput.vue
Normal file
51
src/ui/components/controls/labeledNumberInput.vue
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-labeled-input"
|
||||||
|
:title="title">
|
||||||
|
<div class="c-labeled-input__label">{{ label }}</div>
|
||||||
|
<input type="number"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-bind:value="value"
|
||||||
|
v-on="inputListeners"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/* Emits input and clear events */
|
||||||
|
export default {
|
||||||
|
inheritAttrs: false,
|
||||||
|
props: {
|
||||||
|
value: String,
|
||||||
|
label: String,
|
||||||
|
title: String
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
inputListeners: function () {
|
||||||
|
let vm = this;
|
||||||
|
return Object.assign({},
|
||||||
|
this.$listeners,
|
||||||
|
{
|
||||||
|
input: function (event) {
|
||||||
|
vm.$emit('input', event.target.value);
|
||||||
|
},
|
||||||
|
change: function (event) {
|
||||||
|
vm.$emit('change', event.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
// active: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clearInput() {
|
||||||
|
// Clear the user's input and set 'active' to false
|
||||||
|
this.value = '';
|
||||||
|
this.$emit('clear','');
|
||||||
|
this.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -152,7 +152,7 @@
|
|||||||
|
|
||||||
&__collapse-button {
|
&__collapse-button {
|
||||||
$m: 2px;
|
$m: 2px;
|
||||||
$h: 12px; //nth($splitterBtnD, 1) - ($m * 2);
|
$h: 12px;
|
||||||
color: $splitterBtnColorFg;
|
color: $splitterBtnColorFg;
|
||||||
flex: 0 0 nth($splitterBtnD, 1);
|
flex: 0 0 nth($splitterBtnD, 1);
|
||||||
font-size: $h * .9;
|
font-size: $h * .9;
|
||||||
@ -192,6 +192,7 @@
|
|||||||
// Name of the pane
|
// Name of the pane
|
||||||
@include ellipsize();
|
@include ellipsize();
|
||||||
display: block;
|
display: block;
|
||||||
|
padding-right: nth($splitterBtnD, 2) + $interiorMargin; // Force label to ellipsis
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
flex: 1 0 90%;
|
flex: 1 0 90%;
|
||||||
|
@ -1,56 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-search"
|
<div class="c-search"
|
||||||
:class="{ 'is-active': active === true }">
|
:class="{ 'is-active': active === true }">
|
||||||
<input class="c-search__input" type="search"
|
<input class="c-search__input"
|
||||||
v-bind:value="searchInput"
|
tabindex="10000"
|
||||||
@input="handleInput($event)"/>
|
type="search"
|
||||||
|
v-bind="$attrs"
|
||||||
|
v-bind:value="value"
|
||||||
|
v-on="inputListeners"/>
|
||||||
<a class="c-search__clear-input icon-x-in-circle"
|
<a class="c-search__clear-input icon-x-in-circle"
|
||||||
v-on:click="clearInput"></a>
|
v-on:click="clearInput"></a>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~styles/sass-base";;
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
/******************************* SEARCH */
|
|
||||||
.c-search {
|
.c-search {
|
||||||
@include nice-input();
|
@include wrappedInput();
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
padding-top: 2px;
|
||||||
padding: 2px 4px;
|
padding-bottom: 2px;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// Mag glass icon
|
// Mag glass icon
|
||||||
content: $glyph-icon-magnify;
|
content: $glyph-icon-magnify;
|
||||||
direction: rtl; // Aligns glyph to right-hand side of container, for transition
|
|
||||||
display: block;
|
|
||||||
font-family: symbolsfont;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
opacity: 0.5;
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 2px 0; // Prevents clipping
|
|
||||||
transition: width 250ms ease;
|
|
||||||
width: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: inset rgba(black, 0.8) 0 0px 2px;
|
|
||||||
&:before {
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--major {
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__input {
|
|
||||||
background: none !important;
|
|
||||||
box-shadow: none !important; // !important needed to override default for [input]
|
|
||||||
flex: 0 1 100%;
|
|
||||||
padding-left: 2px !important;
|
|
||||||
padding-right: 2px !important;
|
|
||||||
min-width: 10px; // Must be set to allow input to collapse below browser min
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&__clear-input {
|
&__clear-input {
|
||||||
@ -58,11 +31,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
&.is-active {
|
&.is-active {
|
||||||
&:before {
|
|
||||||
padding: 2px 0px;
|
|
||||||
width: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-search__clear-input {
|
.c-search__clear-input {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
@ -71,26 +39,36 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
/* Emits input and clear events */
|
||||||
export default {
|
export default {
|
||||||
|
inheritAttrs: false,
|
||||||
props: {
|
props: {
|
||||||
value: String
|
value: String
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
inputListeners: function () {
|
||||||
|
let vm = this;
|
||||||
|
return Object.assign({},
|
||||||
|
this.$listeners,
|
||||||
|
{
|
||||||
|
input: function (event) {
|
||||||
|
vm.$emit('input', event.target.value);
|
||||||
|
vm.active = (event.target.value.length > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {
|
||||||
searchInput: '',
|
|
||||||
active: false
|
active: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleInput(e) {
|
|
||||||
// Grab input as the user types it
|
|
||||||
// and set 'active' based on input length > 0
|
|
||||||
this.searchInput = e.target.value;
|
|
||||||
this.active = (this.searchInput.length > 0);
|
|
||||||
},
|
|
||||||
clearInput() {
|
clearInput() {
|
||||||
// Clear the user's input and set 'active' to false
|
// Clear the user's input and set 'active' to false
|
||||||
this.searchInput = '';
|
this.value = '';
|
||||||
|
this.$emit('clear','');
|
||||||
this.active = false;
|
this.active = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,133 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="c-splitter" :class="{
|
|
||||||
'c-splitter-vertical' : align === 'vertical',
|
|
||||||
'c-splitter-horizontal' : align === 'horizontal',
|
|
||||||
'c-splitter-collapse-left' : collapse === 'to-left',
|
|
||||||
'c-splitter-collapse-right' : collapse === 'to-right',
|
|
||||||
}">
|
|
||||||
<a class="c-splitter__btn"></a>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "~styles/constants";
|
|
||||||
@import "~styles/constants-snow";
|
|
||||||
@import "~styles/mixins";
|
|
||||||
@import "~styles/glyphs";
|
|
||||||
|
|
||||||
$c: #06f;
|
|
||||||
$size: $splitterHandleD;
|
|
||||||
$margin: 0px;
|
|
||||||
$hitMargin: 4px;
|
|
||||||
|
|
||||||
|
|
||||||
.c-splitter {
|
|
||||||
background: $colorSplitterBg;
|
|
||||||
transition: $transOut;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
// Bigger hit area
|
|
||||||
//@include test();
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active, &:hover {
|
|
||||||
transition: $transIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background: $colorSplitterActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $colorSplitterHover;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-vertical {
|
|
||||||
cursor: col-resize;
|
|
||||||
width: $size;
|
|
||||||
margin: 0 $margin;
|
|
||||||
&:before {
|
|
||||||
top: 0;
|
|
||||||
right: $hitMargin * -1;
|
|
||||||
bottom: 0;
|
|
||||||
left: $hitMargin * -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&-horizontal {
|
|
||||||
cursor: row-resize;
|
|
||||||
height: $size;
|
|
||||||
margin: $margin 0;
|
|
||||||
&:before {
|
|
||||||
top: $hitMargin * -1;
|
|
||||||
right: 0;
|
|
||||||
bottom: $hitMargin * -1;
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-splitter__btn {
|
|
||||||
// Collapse button
|
|
||||||
background: $colorSplitterBg;
|
|
||||||
display: none; // Only display if splitter is collapsible, see below
|
|
||||||
width: $splitterD;
|
|
||||||
height: 40px;
|
|
||||||
transition: $transOut;
|
|
||||||
|
|
||||||
&:active, &:hover {
|
|
||||||
transition: $transIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $colorSplitterHover;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
background: $colorSplitterActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
[class*="collapse"] & {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 3;
|
|
||||||
&:before {
|
|
||||||
color: $colorSplitterFg;
|
|
||||||
display: block;
|
|
||||||
font-size: 0.8em;
|
|
||||||
font-family: symbolsfont;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[class*="collapse-left"] & {
|
|
||||||
border-bottom-left-radius: $controlCr;
|
|
||||||
right: 0;
|
|
||||||
&:before {
|
|
||||||
content: $glyph-icon-arrow-left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[class*="collapse-right"] & {
|
|
||||||
border-bottom-right-radius: $controlCr;
|
|
||||||
left: 0;
|
|
||||||
&:before {
|
|
||||||
content: $glyph-icon-arrow-right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
align: String,
|
|
||||||
collapse: String
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
176
src/ui/components/controls/toggleButton.vue
Normal file
176
src/ui/components/controls/toggleButton.vue
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-togglebutton">
|
||||||
|
<input type="checkbox"
|
||||||
|
:id="id"
|
||||||
|
:name="name"
|
||||||
|
:value="value"
|
||||||
|
:required="required"
|
||||||
|
:disabled="disabled"
|
||||||
|
@change="onChange"
|
||||||
|
:checked="state">
|
||||||
|
<label :for="id">
|
||||||
|
<div class="c-togglebutton__on"
|
||||||
|
:class="innerClassOn"></div>
|
||||||
|
<div class="c-togglebutton__off"
|
||||||
|
:class="innerClassOff"></div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
.c-togglebutton {
|
||||||
|
$d: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.c-togglebutton__on {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&:checked + label {
|
||||||
|
.c-togglebutton__on {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.c-togglebutton__off {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled) + label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled + label {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
/*
|
||||||
|
Toggle button control, based on checkboxCustom. Use just like a checkbox in HTML.
|
||||||
|
Requires inner-class-on and -off attributes to be passed.
|
||||||
|
Supports checked and disabled attributes.
|
||||||
|
Example usage:
|
||||||
|
<toggle-button checked
|
||||||
|
class="c-click-icon"
|
||||||
|
inner-class-on="icon-grid-snap-to"
|
||||||
|
inner-class-off="icon-grid-snap-no"></toggle-button>
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
model: {
|
||||||
|
prop: 'modelValue',
|
||||||
|
event: 'input'
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
innerClassOn: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
innerClassOff: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
default: function () {
|
||||||
|
return 'checkbox-id-' + this._uid;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
value: {
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
modelValue: {
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
checked: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
required: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
model: {}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
state() {
|
||||||
|
if (this.modelValue === undefined) {
|
||||||
|
return this.checked;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(this.modelValue)) {
|
||||||
|
return this.modelValue.indexOf(this.value) > -1;
|
||||||
|
}
|
||||||
|
return !!this.modelValue;
|
||||||
|
},
|
||||||
|
stateClass() {
|
||||||
|
return this.onClass;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onChange() {
|
||||||
|
this.toggle();
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle() {
|
||||||
|
let value;
|
||||||
|
|
||||||
|
if (Array.isArray(this.modelValue)) {
|
||||||
|
value = this.modelValue.slice(0);
|
||||||
|
|
||||||
|
if (this.state) {
|
||||||
|
value.splice(value.indexOf(this.value), 1);
|
||||||
|
} else {
|
||||||
|
value.push(this.value);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
value = !this.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('input', value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
checked(newValue) {
|
||||||
|
if (newValue !== this.state) {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
if (this.checked && !this.state) {
|
||||||
|
this.toggle();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
@ -1,43 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="c-view-control"
|
<span class="c-disclosure-triangle"
|
||||||
:class="{
|
:class="{
|
||||||
'c-view-control--expanded' : expanded,
|
'c-disclosure-triangle--expanded' : expanded,
|
||||||
'is-enabled' : enabled
|
'is-enabled' : enabled
|
||||||
}"
|
}"
|
||||||
@click="toggle"></span>
|
@click="toggle"></span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "~styles/sass-base";;
|
|
||||||
|
|
||||||
.c-view-control {
|
|
||||||
$d: 12px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
width: $d;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&.is-enabled:before {
|
|
||||||
$s: .65;
|
|
||||||
content: $glyph-icon-arrow-right-equilateral;
|
|
||||||
display: block;
|
|
||||||
font-family: symbolsfont;
|
|
||||||
font-size: 1rem * $s;
|
|
||||||
position: absolute;
|
|
||||||
transform-origin: floor(($d / 2) * $s); // This is slightly better than 'center'
|
|
||||||
transition: transform 100ms ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--expanded {
|
|
||||||
&:before {
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
177
src/ui/components/layout/BrowseBar.vue
Normal file
177
src/ui/components/layout/BrowseBar.vue
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
<template>
|
||||||
|
<div class="l-browse-bar">
|
||||||
|
<div class="l-browse-bar__start">
|
||||||
|
<a class="l-browse-bar__nav-to-parent-button c-click-icon icon-pointer-left"></a>
|
||||||
|
<div class="l-browse-bar__object-name--w"
|
||||||
|
:class="type.cssClass">
|
||||||
|
<span
|
||||||
|
class="l-browse-bar__object-name c-input-inline"
|
||||||
|
v-on:blur="updateName"
|
||||||
|
contenteditable>
|
||||||
|
{{ domainObject.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="l-browse-bar__context-actions c-disclosure-button"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="l-browse-bar__end">
|
||||||
|
<div class="l-browse-bar__view-switcher c-menu-button--w c-menu-button--menus-left"
|
||||||
|
v-if="views.length > 1">
|
||||||
|
<div class="c-button--menu"
|
||||||
|
:class="currentView.cssClass"
|
||||||
|
title="Switch view type"
|
||||||
|
@click="toggleViewMenu">
|
||||||
|
<span class="c-button__label">
|
||||||
|
{{ currentView.name }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu" v-show="showViewMenu">
|
||||||
|
<ul>
|
||||||
|
<li v-for="(view, index) in views"
|
||||||
|
@click="setView(view)"
|
||||||
|
:key="index"
|
||||||
|
:class="view.cssClass"
|
||||||
|
:title="view.name">
|
||||||
|
{{ view.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Action buttons -->
|
||||||
|
<div class="l-browse-bar__actions">
|
||||||
|
<div class="l-browse-bar__action c-button icon-eye-open" title="Preview"></div>
|
||||||
|
<div class="l-browse-bar__action c-button icon-notebook" title="New Notebook entry"></div>
|
||||||
|
<div class="l-browse-bar__action c-button c-button--major icon-pencil" title="Edit"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
|
methods: {
|
||||||
|
toggleViewMenu: function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.showViewMenu = !this.showViewMenu;
|
||||||
|
},
|
||||||
|
updateName: function (event) {
|
||||||
|
// TODO: handle isssues with contenteditable text escaping.
|
||||||
|
if (event.target.innerText !== this.domainObject.name) {
|
||||||
|
this.openmct.objects.mutate(this.domainObject, 'name', event.target.innerText);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setView: function (view) {
|
||||||
|
this.viewKey = view.key;
|
||||||
|
this.openmct.router.updateParams({
|
||||||
|
view: this.viewKey
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
showViewMenu: false,
|
||||||
|
domainObject: {},
|
||||||
|
viewKey: undefined
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentView() {
|
||||||
|
return this.views.filter(v => v.key === this.viewKey)[0] || {};
|
||||||
|
},
|
||||||
|
views() {
|
||||||
|
return this
|
||||||
|
.openmct
|
||||||
|
.objectViews
|
||||||
|
.get(this.domainObject)
|
||||||
|
.map((p) => {
|
||||||
|
return {
|
||||||
|
key: p.key,
|
||||||
|
cssClass: p.cssClass,
|
||||||
|
name: p.name
|
||||||
|
};
|
||||||
|
});
|
||||||
|
},
|
||||||
|
type() {
|
||||||
|
let objectType = this.openmct.types.get(this.domainObject.type);
|
||||||
|
if (!objectType) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
return objectType.definition;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
document.addEventListener('click', () => {
|
||||||
|
if (this.showViewMenu) {
|
||||||
|
this.showViewMenu = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
/******************************* START */
|
||||||
|
|
||||||
|
.l-browse-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
[class*="__"] {
|
||||||
|
// Removes extraneous horizontal white space
|
||||||
|
display: inline-flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__start {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
font-size: 1.4em;
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
min-width: 0; // Forces interior to compress when pushed on
|
||||||
|
}
|
||||||
|
|
||||||
|
&__end {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
[class*="__"] + [class*="__"] {
|
||||||
|
margin-left: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__nav-to-parent-button,
|
||||||
|
&__disclosure-button {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__nav-to-parent-button {
|
||||||
|
// This is an icon-button
|
||||||
|
$p: $interiorMarginLg;
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
padding-left: $p;
|
||||||
|
padding-right: $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__object-name--w {
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
flex: 0 1 auto;
|
||||||
|
min-width: 0;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Icon
|
||||||
|
opacity: 0.5;
|
||||||
|
margin-right: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__object-name {
|
||||||
|
flex: 0 1 auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,159 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
|
|
||||||
// Find an object in an array of objects.
|
|
||||||
function findObject(domainObjects, id) {
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < domainObjects.length; i += 1) {
|
|
||||||
if (domainObjects[i].getId() === id) {
|
|
||||||
return domainObjects[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// recursively locate and return an object inside of a container
|
|
||||||
// via a path. If at any point in the recursion it fails to find
|
|
||||||
// the next object, it will return the parent.
|
|
||||||
function findViaComposition(containerObject, path) {
|
|
||||||
var nextId = path.shift();
|
|
||||||
if (!nextId) {
|
|
||||||
return containerObject;
|
|
||||||
}
|
|
||||||
return containerObject.useCapability('composition')
|
|
||||||
.then(function (composees) {
|
|
||||||
var nextObject = findObject(composees, nextId);
|
|
||||||
if (!nextObject) {
|
|
||||||
return containerObject;
|
|
||||||
}
|
|
||||||
if (!nextObject.hasCapability('composition')) {
|
|
||||||
return nextObject;
|
|
||||||
}
|
|
||||||
return findViaComposition(nextObject, path);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLastChildIfRoot(object) {
|
|
||||||
if (object.getId() !== 'ROOT') {
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
return object.useCapability('composition')
|
|
||||||
.then(function (composees) {
|
|
||||||
return composees[composees.length - 1];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function pathForObject(domainObject) {
|
|
||||||
var context = domainObject.getCapability('context'),
|
|
||||||
objectPath = context ? context.getPath() : [],
|
|
||||||
ids = objectPath.map(function (domainObj) {
|
|
||||||
return domainObj.getId();
|
|
||||||
});
|
|
||||||
return "/browse/" + ids.slice(1).join("/");
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
inject: ["openmct"],
|
|
||||||
mounted() {
|
|
||||||
let openmct = this.openmct;
|
|
||||||
let $injector = openmct.$injector;
|
|
||||||
let angular = openmct.$angular;
|
|
||||||
|
|
||||||
this.objectService = $injector.get('objectService');
|
|
||||||
this.templateLinker = $injector.get('templateLinker');
|
|
||||||
this.navigationService = $injector.get('navigationService');
|
|
||||||
this.$timeout = $injector.get('$timeout');
|
|
||||||
|
|
||||||
this.templateMap = {};
|
|
||||||
$injector.get('templates[]').forEach((t) => {
|
|
||||||
this.templateMap[t.key] = this.templateMap[t.key] || t;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.$rootScope = $injector.get('$rootScope');
|
|
||||||
this.$scope = this.$rootScope.$new();
|
|
||||||
this.$scope.representation = {};
|
|
||||||
|
|
||||||
openmct.router.route(/^\/browse\/(.*)$/, (path, results) => {
|
|
||||||
let navigatePath = results[1];
|
|
||||||
if (!navigatePath) {
|
|
||||||
navigatePath = 'mine';
|
|
||||||
}
|
|
||||||
this.navigateToPath(navigatePath);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.navigationService.addListener(o => this.navigateToObject(o));
|
|
||||||
},
|
|
||||||
destroyed() {
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
navigateToPath(path) {
|
|
||||||
if (!Array.isArray(path)) {
|
|
||||||
path = path.split('/');
|
|
||||||
}
|
|
||||||
return this.getObject('ROOT')
|
|
||||||
.then(root => {
|
|
||||||
return findViaComposition(root, path);
|
|
||||||
})
|
|
||||||
.then(getLastChildIfRoot)
|
|
||||||
.then(object => {
|
|
||||||
this.setMainViewObject(object);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
setMainViewObject(object) {
|
|
||||||
this.$scope.domainObject = object;
|
|
||||||
this.$scope.navigatedObject = object;
|
|
||||||
this.templateLinker.link(
|
|
||||||
this.$scope,
|
|
||||||
this.openmct.$angular.element(this.$el),
|
|
||||||
this.templateMap["browseObject"]
|
|
||||||
);
|
|
||||||
document.title = object.getModel().name;
|
|
||||||
this.scheduleDigest();
|
|
||||||
},
|
|
||||||
|
|
||||||
idsForObject(domainObject) {
|
|
||||||
return this.urlService
|
|
||||||
.urlForLocation("", domainObject)
|
|
||||||
.replace('/', '');
|
|
||||||
},
|
|
||||||
|
|
||||||
navigateToObject(object) {
|
|
||||||
let path = pathForObject(object);
|
|
||||||
let views = object.useCapability('view');
|
|
||||||
let params = this.openmct.router.getParams();
|
|
||||||
let currentViewIsValid = views.some(v => v.key === params['view']);
|
|
||||||
if (!currentViewIsValid) {
|
|
||||||
this.scope.representation = {
|
|
||||||
selected: views[0]
|
|
||||||
}
|
|
||||||
this.openmct.router.update(path, {
|
|
||||||
view: views[0].key
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.openmct.router.setPath(path);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
scheduleDigest() {
|
|
||||||
this.$timeout(function () {
|
|
||||||
// digest done!
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getObject(id) {
|
|
||||||
return this.objectService.getObjects([id])
|
|
||||||
.then(function (results) {
|
|
||||||
return results[id];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
|
|
@ -3,10 +3,8 @@
|
|||||||
<div class="l-shell__head">
|
<div class="l-shell__head">
|
||||||
<CreateButton class="l-shell__create-button"></CreateButton>
|
<CreateButton class="l-shell__create-button"></CreateButton>
|
||||||
<div class="l-shell__controls">
|
<div class="l-shell__controls">
|
||||||
<div class="l-controls__elem c-button-set">
|
<a class="c-click-icon icon-new-window" title="Open in a new browser tab"></a>
|
||||||
<a class="c-icon-button icon-new-window" title="Open in a new browser tab"></a>
|
<a class="c-click-icon icon-fullscreen-collapse" title="Enable full screen mode"></a>
|
||||||
<a class="c-icon-button icon-fullscreen-collapse" title="Enable full screen mode"></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="l-shell__app-logo">[ App Logo ]</div>
|
<div class="l-shell__app-logo">[ App Logo ]</div>
|
||||||
</div>
|
</div>
|
||||||
@ -23,12 +21,15 @@
|
|||||||
<mct-tree></mct-tree>
|
<mct-tree></mct-tree>
|
||||||
</div>
|
</div>
|
||||||
</pane>
|
</pane>
|
||||||
<pane class="l-shell__pane-main">
|
<pane class="l-shell__pane-main"
|
||||||
<browse-object class="l-shell__main-container">
|
:class="{ 'is-editing' : true }">
|
||||||
</browse-object>
|
<browse-bar class="l-shell__main-view-browse-bar"
|
||||||
|
ref="browseBar"></browse-bar>
|
||||||
|
<toolbar class="l-shell__toolbar"></toolbar>
|
||||||
|
<object-view class="l-shell__main-container"
|
||||||
|
ref="browseObject"></object-view>
|
||||||
<mct-template template-key="conductor"
|
<mct-template template-key="conductor"
|
||||||
class="l-shell__time-conductor">
|
class="l-shell__time-conductor"></mct-template>
|
||||||
</mct-template>
|
|
||||||
</pane>
|
</pane>
|
||||||
<pane class="l-shell__pane-inspector l-pane--holds-multipane"
|
<pane class="l-shell__pane-inspector l-pane--holds-multipane"
|
||||||
handle="before"
|
handle="before"
|
||||||
@ -82,7 +83,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__pane-main {
|
&__pane-main,
|
||||||
|
&__pane-tree {
|
||||||
> .l-pane__contents {
|
> .l-pane__contents {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column nowrap;
|
flex-flow: column nowrap;
|
||||||
@ -117,11 +119,15 @@
|
|||||||
|
|
||||||
&__head,
|
&__head,
|
||||||
&__status {
|
&__status {
|
||||||
flex: 0 1 auto;
|
flex: 0 0 auto;
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************* HEAD */
|
/******************************* HEAD */
|
||||||
|
&__main-view-browse-bar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
&__head {
|
&__head {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -145,11 +151,12 @@
|
|||||||
margin-right: 2.5%;
|
margin-right: 2.5%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/********** MAIN AREA */
|
/******************************* MAIN AREA */
|
||||||
&__main-container {
|
&__main-container {
|
||||||
// Wrapper for main views
|
// Wrapper for main views
|
||||||
flex: 1 1 100%;
|
flex: 1 1 auto;
|
||||||
font-size: 16px; // TEMP FOR LEGACY STYLING
|
overflow: auto;
|
||||||
|
//font-size: 16px; // TEMP FOR LEGACY STYLING
|
||||||
}
|
}
|
||||||
|
|
||||||
&__tree {
|
&__tree {
|
||||||
@ -178,6 +185,11 @@
|
|||||||
&__pane-inspector {
|
&__pane-inspector {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__toolbar {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
margin-bottom: $interiorMargin;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@ -186,26 +198,30 @@
|
|||||||
import Inspector from '../inspector/Inspector.vue';
|
import Inspector from '../inspector/Inspector.vue';
|
||||||
import MctStatus from './MctStatus.vue';
|
import MctStatus from './MctStatus.vue';
|
||||||
import MctTree from './mct-tree.vue';
|
import MctTree from './mct-tree.vue';
|
||||||
import BrowseObject from './BrowseObject.vue';
|
import ObjectView from './ObjectView.vue';
|
||||||
import MctTemplate from '../legacy/mct-template.vue';
|
import MctTemplate from '../legacy/mct-template.vue';
|
||||||
import ContextMenu from '../controls/ContextMenu.vue';
|
import ContextMenu from '../controls/ContextMenu.vue';
|
||||||
import CreateButton from '../controls/CreateButton.vue';
|
import CreateButton from '../controls/CreateButton.vue';
|
||||||
import search from '../controls/search.vue';
|
import search from '../controls/search.vue';
|
||||||
import multipane from '../controls/multipane.vue';
|
import multipane from '../controls/multipane.vue';
|
||||||
import pane from '../controls/pane.vue';
|
import pane from '../controls/pane.vue';
|
||||||
|
import BrowseBar from './BrowseBar.vue';
|
||||||
|
import Toolbar from './Toolbar.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Inspector,
|
Inspector,
|
||||||
MctStatus,
|
MctStatus,
|
||||||
MctTree,
|
MctTree,
|
||||||
BrowseObject,
|
ObjectView,
|
||||||
'mct-template': MctTemplate,
|
'mct-template': MctTemplate,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
CreateButton,
|
CreateButton,
|
||||||
search,
|
search,
|
||||||
multipane,
|
multipane,
|
||||||
pane
|
pane,
|
||||||
|
BrowseBar,
|
||||||
|
Toolbar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
75
src/ui/components/layout/ObjectView.vue
Normal file
75
src/ui/components/layout/ObjectView.vue
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.c-object-view {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import _ from "lodash"
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ["openmct"],
|
||||||
|
props: {
|
||||||
|
view: String,
|
||||||
|
object: Object
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.clear();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
view(newView, oldView) {
|
||||||
|
this.viewKey = newView;
|
||||||
|
this.debounceUpdateView();
|
||||||
|
},
|
||||||
|
object(newObject, oldObject) {
|
||||||
|
this.currentObject = newObject;
|
||||||
|
this.debounceUpdateView();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.debounceUpdateView = _.debounce(this.updateView, 10);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.currentObject = this.object;
|
||||||
|
this.updateView();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
clear() {
|
||||||
|
if (this.currentView) {
|
||||||
|
this.currentView.destroy();
|
||||||
|
this.$el.innerHTML = '';
|
||||||
|
}
|
||||||
|
delete this.viewContainer;
|
||||||
|
delete this.currentView;
|
||||||
|
},
|
||||||
|
updateView() {
|
||||||
|
this.clear();
|
||||||
|
if (!this.currentObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.viewContainer = document.createElement('div');
|
||||||
|
this.viewContainer.classList.add('c-object-view');
|
||||||
|
this.$el.append(this.viewContainer);
|
||||||
|
let provider = this.openmct.objectViews.getByProviderKey(this.viewKey);
|
||||||
|
if (!provider) {
|
||||||
|
provider = this.openmct.objectViews.get(this.currentObject)[0];
|
||||||
|
if (!provider) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.currentView = provider.view(this.currentObject);
|
||||||
|
this.currentView.show(this.viewContainer);
|
||||||
|
},
|
||||||
|
show(object, viewKey) {
|
||||||
|
this.currentObject = object;
|
||||||
|
this.viewKey = viewKey;
|
||||||
|
this.updateView();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
291
src/ui/components/layout/Toolbar.vue
Normal file
291
src/ui/components/layout/Toolbar.vue
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-toolbar">
|
||||||
|
<!-- VERSION MANUALLY RESTORED FROM VUE-LAYOUT -->
|
||||||
|
<div class="c-button-set">
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-button--menu js-add-button icon-plus"
|
||||||
|
@click="toggleMenus">
|
||||||
|
<div class="c-button__label">Add</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu" v-if="showMenus">
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in addMenuItems"
|
||||||
|
:class="item.class"
|
||||||
|
:title="item.title">
|
||||||
|
{{ item.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<div class="c-ctrl-wrapper"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<div class="c-click-icon c-click-icon--menu js-layers icon-layers"
|
||||||
|
@click="toggleMenus"></div>
|
||||||
|
<div class="c-menu" v-if="showMenus">
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in layersMenuItems"
|
||||||
|
:class="item.class"
|
||||||
|
:title="item.title">
|
||||||
|
{{ item.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-ctrl-wrapper"
|
||||||
|
v-if="toolsColorFill">
|
||||||
|
<div class="c-click-icon c-click-icon--swatched js-color-fill icon-paint-bucket"
|
||||||
|
@click="toggleMenus">
|
||||||
|
<div class="c-swatch" style="background: #33ff00;"></div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu c-palette c-palette--color"
|
||||||
|
v-if="showMenus">
|
||||||
|
<div class="c-palette__item-none"
|
||||||
|
vif="this.palette.itemNone === true">
|
||||||
|
<div class="c-palette__item"
|
||||||
|
@click="this.setColor('no-color')"></div>
|
||||||
|
No fill
|
||||||
|
</div>
|
||||||
|
<div class="c-palette__items">
|
||||||
|
<div class="c-palette__item"
|
||||||
|
v-for="color in colorPalette"
|
||||||
|
:style="{ background: color.value }"
|
||||||
|
@click="this.setColor(color.value)"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-ctrl-wrapper"
|
||||||
|
v-if="toolsColorStroke">
|
||||||
|
<div class="c-click-icon c-click-icon--swatched js-color-stroke icon-pencil">
|
||||||
|
<div class="c-toolbar-button__swatch" style="background: #ffffff;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-ctrl-wrapper"
|
||||||
|
v-if="toolsColorText">
|
||||||
|
<div class="c-click-icon c-click-icon--swatched js-color-text icon-font">
|
||||||
|
<div class="c-toolbar-button__swatch" style="background: #333333;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected && toolsFontSize">
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon c-click-icon--menu js-font-size"
|
||||||
|
@click="toggleMenus">
|
||||||
|
<div class="c-button__label">11 px</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu" v-if="showMenus">
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in fontSizeMenuItems">
|
||||||
|
{{ item.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected && toolsEditProperties">
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon js-image icon-gear"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<labeledNumberInput label="X" value=1 title="X position"></labeledNumberInput>
|
||||||
|
<labeledNumberInput label="Y" value=2 title="Y position"></labeledNumberInput>
|
||||||
|
<labeledNumberInput label="W" value=3 title="Width"></labeledNumberInput>
|
||||||
|
<labeledNumberInput label="H" value=4 title="Height"></labeledNumberInput>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<div class="c-click-icon c-click-icon--caution icon-trash"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<checkbox checked title="This is a checkbox">Checkbox</checkbox>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="c-button-set"
|
||||||
|
v-if="toolsItemSelected">
|
||||||
|
<toggle-button title="Toggle frame" checked
|
||||||
|
class="c-click-icon"
|
||||||
|
inner-class-on="icon-frame-show"
|
||||||
|
inner-class-off="icon-frame-hide"></toggle-button>
|
||||||
|
<toggle-button title="Snap to grid" checked
|
||||||
|
class="c-click-icon"
|
||||||
|
inner-class-on="icon-grid-snap-to"
|
||||||
|
inner-class-off="icon-grid-snap-no"></toggle-button>
|
||||||
|
<toggle-button title="Show label and value" checked
|
||||||
|
class="c-click-icon"
|
||||||
|
inner-class-on="icon-two-parts-both"
|
||||||
|
inner-class-off="icon-two-parts-one-only"></toggle-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import labeledNumberInput from '../controls/labeledNumberInput.vue';
|
||||||
|
import checkbox from '../controls/checkboxCustom.vue';
|
||||||
|
import toggleButton from '../controls/toggleButton.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
labeledNumberInput,
|
||||||
|
checkbox,
|
||||||
|
toggleButton
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleMenus: function () {
|
||||||
|
this.showMenus = !this.showMenus;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
toolsItemSelected: { type: Boolean, default: true },
|
||||||
|
toolsColorFill: { type: Boolean, default: true },
|
||||||
|
toolsColorStroke: { type: Boolean, default: true },
|
||||||
|
toolsColorText: { type: Boolean, default: true },
|
||||||
|
toolsFontSize: { type: Boolean, default: true },
|
||||||
|
toolsEditProperties: { type: Boolean, default: true },
|
||||||
|
toolSetBox: ['toolsColorFill', 'toolsColorStroke'],
|
||||||
|
toolSetLine: ['toolsColorStroke'],
|
||||||
|
toolSetText: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsEditProperties'],
|
||||||
|
toolSetImage: ['toolsColorStroke', 'toolsEditProperties'],
|
||||||
|
toolSetTelemetry: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsLabelValue']
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
showMenus: false,
|
||||||
|
addMenuItems: [
|
||||||
|
{ name: 'Box', class: 'icon-box', title: 'Add Box' },
|
||||||
|
{ name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
|
||||||
|
{ name: 'Text', class: 'icon-font', title: 'Add Text' },
|
||||||
|
{ name: 'Image', class: 'icon-image', title: 'Add Image' }
|
||||||
|
],
|
||||||
|
layersMenuItems: [
|
||||||
|
{ name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
|
||||||
|
{ name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
|
||||||
|
{ name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
|
||||||
|
{ name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
|
||||||
|
],
|
||||||
|
fontSizeMenuItems: [
|
||||||
|
{ value: '9', name: '9 px' },
|
||||||
|
{ value: '10', name: '10 px' },
|
||||||
|
{ value: '11', name: '11 px' },
|
||||||
|
{ value: '12', name: '12 px' },
|
||||||
|
{ value: '13', name: '13 px' },
|
||||||
|
{ value: '14', name: '14 px' },
|
||||||
|
{ value: '16', name: '16 px' },
|
||||||
|
{ value: '18', name: '18 px' },
|
||||||
|
{ value: '20', name: '20 px' },
|
||||||
|
{ value: '24', name: '24 px' },
|
||||||
|
{ value: '28', name: '28 px' },
|
||||||
|
{ value: '32', name: '32 px' },
|
||||||
|
{ value: '40', name: '40 px' },
|
||||||
|
{ value: '48', name: '48 px' },
|
||||||
|
{ value: '56', name: '56 px' },
|
||||||
|
{ value: '64', name: '64 px' },
|
||||||
|
{ value: '72', name: '72 px' },
|
||||||
|
{ value: '80', name: '80 px' },
|
||||||
|
{ value: '88', name: '88 px' },
|
||||||
|
{ value: '96', name: '96 px' },
|
||||||
|
{ value: '128', name: '128 px' },
|
||||||
|
{ value: '160', name: '160 px' }
|
||||||
|
],
|
||||||
|
colorPalette: [
|
||||||
|
{ value: '#000000' },
|
||||||
|
{ value: '#434343' },
|
||||||
|
{ value: '#666666' },
|
||||||
|
{ value: '#999999' },
|
||||||
|
{ value: '#b7b7b7' },
|
||||||
|
{ value: '#cccccc' },
|
||||||
|
{ value: '#d9d9d9' },
|
||||||
|
{ value: '#efefef' },
|
||||||
|
{ value: '#f3f3f3' },
|
||||||
|
{ value: '#ffffff' },
|
||||||
|
{ value: '#980000' },
|
||||||
|
{ value: '#ff0000' },
|
||||||
|
{ value: '#ff9900' },
|
||||||
|
{ value: '#ffff00' },
|
||||||
|
{ value: '#00ff00' },
|
||||||
|
{ value: '#00ffff' },
|
||||||
|
{ value: '#4a86e8' },
|
||||||
|
{ value: '#0000ff' },
|
||||||
|
{ value: '#9900ff' },
|
||||||
|
{ value: '#ff00ff' },
|
||||||
|
{ value: '#e6b8af' },
|
||||||
|
{ value: '#f4cccc' },
|
||||||
|
{ value: '#fce5cd' },
|
||||||
|
{ value: '#fff2cc' },
|
||||||
|
{ value: '#d9ead3' },
|
||||||
|
{ value: '#d0e0e3' },
|
||||||
|
{ value: '#c9daf8' },
|
||||||
|
{ value: '#cfe2f3' },
|
||||||
|
{ value: '#d9d2e9' },
|
||||||
|
{ value: '#ead1dc' },
|
||||||
|
{ value: '#dd7e6b' },
|
||||||
|
{ value: '#dd7e6b' },
|
||||||
|
{ value: '#f9cb9c' },
|
||||||
|
{ value: '#ffe599' },
|
||||||
|
{ value: '#b6d7a8' },
|
||||||
|
{ value: '#a2c4c9' },
|
||||||
|
{ value: '#a4c2f4' },
|
||||||
|
{ value: '#9fc5e8' },
|
||||||
|
{ value: '#b4a7d6' },
|
||||||
|
{ value: '#d5a6bd' },
|
||||||
|
{ value: '#cc4125' },
|
||||||
|
{ value: '#e06666' },
|
||||||
|
{ value: '#f6b26b' },
|
||||||
|
{ value: '#ffd966' },
|
||||||
|
{ value: '#93c47d' },
|
||||||
|
{ value: '#76a5af' },
|
||||||
|
{ value: '#6d9eeb' },
|
||||||
|
{ value: '#6fa8dc' },
|
||||||
|
{ value: '#8e7cc3' },
|
||||||
|
{ value: '#c27ba0' },
|
||||||
|
{ value: '#a61c00' },
|
||||||
|
{ value: '#cc0000' },
|
||||||
|
{ value: '#e69138' },
|
||||||
|
{ value: '#f1c232' },
|
||||||
|
{ value: '#6aa84f' },
|
||||||
|
{ value: '#45818e' },
|
||||||
|
{ value: '#3c78d8' },
|
||||||
|
{ value: '#3d85c6' },
|
||||||
|
{ value: '#674ea7' },
|
||||||
|
{ value: '#a64d79' },
|
||||||
|
{ value: '#85200c' },
|
||||||
|
{ value: '#990000' },
|
||||||
|
{ value: '#b45f06' },
|
||||||
|
{ value: '#bf9000' },
|
||||||
|
{ value: '#38761d' },
|
||||||
|
{ value: '#134f5c' },
|
||||||
|
{ value: '#1155cc' },
|
||||||
|
{ value: '#0b5394' },
|
||||||
|
{ value: '#351c75' },
|
||||||
|
{ value: '#741b47' },
|
||||||
|
{ value: '#5b0f00' },
|
||||||
|
{ value: '#660000' },
|
||||||
|
{ value: '#783f04' },
|
||||||
|
{ value: '#7f6000' },
|
||||||
|
{ value: '#274e13' },
|
||||||
|
{ value: '#0c343d' },
|
||||||
|
{ value: '#1c4587' },
|
||||||
|
{ value: '#073763' },
|
||||||
|
{ value: '#20124d' },
|
||||||
|
{ value: '#4c1130' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -69,7 +69,8 @@
|
|||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// Type icon
|
// Type icon
|
||||||
display: inline-block;
|
display: block;
|
||||||
|
flex: 0 0 auto;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
margin-right: $interiorMarginSm;
|
margin-right: $interiorMarginSm;
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,6 @@ export default {
|
|||||||
|
|
||||||
let $rootScope = $injector.get('$rootScope');
|
let $rootScope = $injector.get('$rootScope');
|
||||||
this.$scope = $rootScope.$new();
|
this.$scope = $rootScope.$new();
|
||||||
console.log('mounting', this.templateKey);
|
|
||||||
console.log('template:', templateMap[this.templateKey]);
|
|
||||||
|
|
||||||
templateLinker.link(
|
templateLinker.link(
|
||||||
this.$scope,
|
this.$scope,
|
||||||
|
@ -101,7 +101,7 @@ class ApplicationRouter extends EventEmitter {
|
|||||||
doPathChange(newPath, oldPath, newLocation) {
|
doPathChange(newPath, oldPath, newLocation) {
|
||||||
let route = this.routes.filter(r => r.matcher.test(newPath))[0];
|
let route = this.routes.filter(r => r.matcher.test(newPath))[0];
|
||||||
if (route) {
|
if (route) {
|
||||||
route.callback(newPath, route.matcher.exec(newPath));
|
route.callback(newPath, route.matcher.exec(newPath), this.currentLocation.params);
|
||||||
}
|
}
|
||||||
this.emit('change:path', newPath, oldPath);
|
this.emit('change:path', newPath, oldPath);
|
||||||
}
|
}
|
||||||
|
80
src/ui/router/Browse.js
Normal file
80
src/ui/router/Browse.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
define([
|
||||||
|
|
||||||
|
], function (
|
||||||
|
|
||||||
|
) {
|
||||||
|
|
||||||
|
return function install(openmct) {
|
||||||
|
let navigateCall = 0;
|
||||||
|
let browseObject;
|
||||||
|
|
||||||
|
|
||||||
|
function viewObject(object, viewProvider) {
|
||||||
|
openmct.layout.$refs.browseObject.show(object, viewProvider.key);
|
||||||
|
openmct.layout.$refs.browseBar.domainObject = object;
|
||||||
|
openmct.layout.$refs.browseBar.viewKey = viewProvider.key;
|
||||||
|
};
|
||||||
|
|
||||||
|
function navigateToPath(path, currentViewKey) {
|
||||||
|
navigateCall++;
|
||||||
|
let currentNavigation = navigateCall;
|
||||||
|
|
||||||
|
if (!Array.isArray(path)) {
|
||||||
|
path = path.split('/');
|
||||||
|
}
|
||||||
|
let keyString = path[path.length - 1];
|
||||||
|
// TODO: retain complete path in navigation.
|
||||||
|
return openmct.objects.get(keyString)
|
||||||
|
.then((object) => {
|
||||||
|
if (currentNavigation !== navigateCall) {
|
||||||
|
return; // Prevent race.
|
||||||
|
}
|
||||||
|
openmct.layout.$refs.browseBar.domainObject = object;
|
||||||
|
browseObject = object;
|
||||||
|
if (!object) {
|
||||||
|
openmct.layout.$refs.browseObject.clear();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let currentProvider = openmct
|
||||||
|
.objectViews
|
||||||
|
.getByProviderKey(currentViewKey)
|
||||||
|
|
||||||
|
if (currentProvider && currentProvider.canView(object)) {
|
||||||
|
viewObject(object, currentProvider);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultProvider = openmct.objectViews.get(object)[0];
|
||||||
|
if (defaultProvider) {
|
||||||
|
openmct.router.updateParams({
|
||||||
|
view: defaultProvider.key
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
openmct.router.updateParams({
|
||||||
|
view: undefined
|
||||||
|
});
|
||||||
|
openmct.layout.$refs.browseObject.clear();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openmct.router.route(/^\/browse\/(.*)$/, (path, results, params) => {
|
||||||
|
let navigatePath = results[1];
|
||||||
|
if (!navigatePath) {
|
||||||
|
navigatePath = 'mine';
|
||||||
|
}
|
||||||
|
navigateToPath(navigatePath, params.view);
|
||||||
|
});
|
||||||
|
|
||||||
|
openmct.router.on('change:params', function (newParams, oldParams, changed) {
|
||||||
|
if (changed.view && browseObject) {
|
||||||
|
let provider = openmct
|
||||||
|
.objectViews
|
||||||
|
.getByProviderKey(changed.view);
|
||||||
|
viewObject(browseObject, provider);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
@ -27,7 +27,7 @@ const webpackConfig = {
|
|||||||
"bourbon": "bourbon.scss",
|
"bourbon": "bourbon.scss",
|
||||||
"espresso": path.join(__dirname, "src/styles/theme-espresso.scss"),
|
"espresso": path.join(__dirname, "src/styles/theme-espresso.scss"),
|
||||||
"snow": path.join(__dirname, "src/styles/theme-snow.scss"),
|
"snow": path.join(__dirname, "src/styles/theme-snow.scss"),
|
||||||
"vue": path.join(__dirname, "node_modules/vue/dist/vue.min.js"),
|
"vue": path.join(__dirname, "node_modules/vue/dist/vue.js"),
|
||||||
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
|
||||||
"styles": path.join(__dirname, "src/styles-new")
|
"styles": path.join(__dirname, "src/styles-new")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user