mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 10:44:21 +00:00
Compare commits
20 Commits
stackplots
...
cli
Author | SHA1 | Date | |
---|---|---|---|
1ea23e53e7 | |||
f6c66248c8 | |||
9bffd0c5d5 | |||
1ddfa671c7 | |||
886ac8e859 | |||
7e121dc647 | |||
83ce018bef | |||
3b6b4a5694 | |||
f8e0dbd5b7 | |||
af5449b78f | |||
c9df2db962 | |||
bc757c09d4 | |||
7b3fe0e1dc | |||
0609c7e0ac | |||
1a802d1e7f | |||
efd2c47a3f | |||
45fb644658 | |||
b0d72c49bc | |||
e2b4c87c03 | |||
f1f8439726 |
22
ideas/cli/bundle.json
Normal file
22
ideas/cli/bundle.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"extensions": {
|
||||
"routes": [
|
||||
{
|
||||
"when": "/cli",
|
||||
"templateUrl": "templates/cli.html"
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "CLIController",
|
||||
"implementation": "CLIController.js",
|
||||
"depends": [ "$scope", "navigationService", "objectService" ]
|
||||
}
|
||||
],
|
||||
"stylesheets": [
|
||||
{
|
||||
"stylesheetUrl": "stylesheets/cli.css"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
47
ideas/cli/res/stylesheets/cli.css
Normal file
47
ideas/cli/res/stylesheets/cli.css
Normal file
@ -0,0 +1,47 @@
|
||||
.iw-container {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.iw-stdin {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 30px;
|
||||
width: calc(100% - 8px);
|
||||
margin: 4px;
|
||||
font-family: monospace;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.iw-stdout {
|
||||
position: absolute;
|
||||
left: 6px;
|
||||
right: 6px;
|
||||
top: 12px;
|
||||
bottom: 44px;
|
||||
border: 1px #211 solid;
|
||||
border-radius: 12px;
|
||||
padding: 8px;
|
||||
background: #302;
|
||||
overflow: auto;
|
||||
box-shadow: inset 0px 2px 8px 0px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.iw-stdout span {
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
color: #FD9;
|
||||
font-size: 16px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
min-height: 1em;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.iw-stdout span.iw-user-input {
|
||||
color: gray;
|
||||
}
|
15
ideas/cli/res/templates/cli.html
Normal file
15
ideas/cli/res/templates/cli.html
Normal file
@ -0,0 +1,15 @@
|
||||
<div class="abs holder-all browse-mode" ng-controller="CLIController">
|
||||
<div class="iw-container">
|
||||
<div class="iw-stdout" mct-scroll-y="stdoutScroll">
|
||||
<span ng-repeat="line in stdout track by $index"
|
||||
class="{{line.cssClass}}"
|
||||
ng-bind="line.text">
|
||||
</span>
|
||||
</div>
|
||||
<form ng-submit="enter(stdin)">
|
||||
<input type="text" class="iw-stdin" ng-model="stdin" autofocus>
|
||||
</form>
|
||||
</div>
|
||||
<mct-include key="'bottombar'"></mct-include>
|
||||
</div>
|
||||
|
177
ideas/cli/src/CLIController.js
Normal file
177
ideas/cli/src/CLIController.js
Normal file
@ -0,0 +1,177 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(function () {
|
||||
'use strict';
|
||||
return function CLIController($scope, navigationService, objectService) {
|
||||
var unlistenToMutation,
|
||||
currentComposition = [];
|
||||
|
||||
function print(str, cssClass) {
|
||||
$scope.stdout.push({
|
||||
text: str,
|
||||
cssClass: cssClass
|
||||
});
|
||||
$scope.stdoutScroll = Number.MAX_VALUE;
|
||||
}
|
||||
|
||||
function pad(str, length) {
|
||||
while (str.length < length) {
|
||||
str += " ";
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
function summarize(domainObject) {
|
||||
var type = domainObject.getCapability("type"),
|
||||
typeName = type ? type.getName() : "Object",
|
||||
location = domainObject.getCapability('location'),
|
||||
isLink = (location && location.isLink()),
|
||||
suffix = isLink ? " (link)" : "";
|
||||
return "[" + typeName + "] " + domainObject.getModel().name + suffix;
|
||||
}
|
||||
|
||||
function printComposition(domainObject) {
|
||||
return domainObject.useCapability("composition").then(function (c) {
|
||||
currentComposition = c;
|
||||
c.forEach(function (childObject, i) {
|
||||
print(i + ") " + summarize(childObject));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function printObject(domainObject, callback) {
|
||||
// Exclude the root object; nobody wants to see that
|
||||
if (domainObject.hasCapability("context")) {
|
||||
print(summarize(domainObject));
|
||||
}
|
||||
if (domainObject.hasCapability('composition')) {
|
||||
printComposition(domainObject).then(callback);
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
function unlisten() {
|
||||
if (unlistenToMutation) {
|
||||
unlistenToMutation();
|
||||
unlistenToMutation = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function navChange(domainObject) {
|
||||
unlisten();
|
||||
unlistenToMutation = domainObject.getCapability("mutation")
|
||||
.listen(function () { printObject(domainObject); });
|
||||
printObject(domainObject);
|
||||
}
|
||||
|
||||
function findTarget(id) {
|
||||
if (id === "this") {
|
||||
return navigationService.getNavigation();
|
||||
} else {
|
||||
return currentComposition[parseInt(id, 10)];
|
||||
}
|
||||
}
|
||||
|
||||
function listActions(domainObject, index) {
|
||||
// Don't show actions for the root
|
||||
if (!domainObject.hasCapability('context')) {
|
||||
return;
|
||||
}
|
||||
|
||||
domainObject.getCapability('action').getActions().forEach(function (a) {
|
||||
var metadata = a.getMetadata(),
|
||||
desc = metadata.description,
|
||||
suffix = index !== undefined ? (" " + index) : "";
|
||||
print(pad(metadata.key + suffix, 32) + (desc || ""));
|
||||
});
|
||||
}
|
||||
|
||||
function performAction(domainObject, action) {
|
||||
domainObject.getCapability('action').perform(action);
|
||||
}
|
||||
|
||||
function handleInput(input) {
|
||||
var parts = input.split(" "),
|
||||
targetObject;
|
||||
|
||||
if (input.length === 0) {
|
||||
targetObject = navigationService.getNavigation();
|
||||
if (targetObject) {
|
||||
printObject(targetObject, function () {
|
||||
print("");
|
||||
listActions(targetObject);
|
||||
});
|
||||
}
|
||||
return;
|
||||
} else if (parts.length === 1) {
|
||||
if (isNaN(parseInt(parts[0], 10))) {
|
||||
targetObject = navigationService.getNavigation();
|
||||
performAction(targetObject, parts[0]);
|
||||
return;
|
||||
}
|
||||
targetObject = findTarget(parts[0]);
|
||||
if (targetObject) {
|
||||
listActions(targetObject, parts[0]);
|
||||
return;
|
||||
}
|
||||
} else if (parts.length === 2) {
|
||||
targetObject = findTarget(parts[1]);
|
||||
if (targetObject) {
|
||||
performAction(targetObject, parts[0]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Any parse-able input should have returned already.
|
||||
print("SYNTAX ERROR. READY.");
|
||||
}
|
||||
|
||||
if (!navigationService.getNavigation()) {
|
||||
objectService.getObjects(["ROOT"]).then(function (objects) {
|
||||
navigationService.setNavigation(objects.ROOT);
|
||||
});
|
||||
}
|
||||
|
||||
navigationService.addListener(navChange);
|
||||
|
||||
$scope.stdout = [];
|
||||
$scope.stdin = "";
|
||||
$scope.stdoutScroll = 0;
|
||||
|
||||
$scope.enter = function (input) {
|
||||
$scope.stdin = "";
|
||||
print("");
|
||||
print(input, "iw-user-input");
|
||||
print("");
|
||||
|
||||
handleInput(input);
|
||||
};
|
||||
|
||||
$scope.$on("$destroy", function () {
|
||||
navigationService.removeListener(navChange);
|
||||
unlisten();
|
||||
});
|
||||
};
|
||||
});
|
@ -105,9 +105,15 @@
|
||||
"actions": [
|
||||
{
|
||||
"key": "navigate",
|
||||
"description": "Browse to this object.",
|
||||
"implementation": "navigation/NavigateAction.js",
|
||||
"depends": [ "navigationService", "$q" ]
|
||||
},
|
||||
{
|
||||
"key": "back",
|
||||
"implementation": "navigation/BackAction.js",
|
||||
"description": "Navigate to the parent of this object."
|
||||
},
|
||||
{
|
||||
"key": "window",
|
||||
"name": "Open In New Tab",
|
||||
|
@ -24,7 +24,7 @@
|
||||
<a
|
||||
class='type-icon icon ui-symbol s-back'
|
||||
ng-show="context.getPath().length > 2"
|
||||
ng-click="context.getParent().getCapability('action').perform('navigate')">
|
||||
ng-click="domainObject.getCapability('action').perform('back')">
|
||||
{
|
||||
</a>
|
||||
|
||||
|
@ -53,11 +53,12 @@ define(
|
||||
*/
|
||||
function CreateAction(type, parent, context, dialogService, creationService, policyService) {
|
||||
this.metadata = {
|
||||
key: 'create',
|
||||
key: 'create.' + type.getKey(),
|
||||
glyph: type.getGlyph(),
|
||||
name: type.getName(),
|
||||
type: type.getKey(),
|
||||
description: type.getDescription(),
|
||||
category: [ 'creation' ],
|
||||
context: context
|
||||
};
|
||||
|
||||
|
@ -63,7 +63,10 @@ define(
|
||||
// domain object to serve as the container for the
|
||||
// newly-created object (although the user may later
|
||||
// make a different selection)
|
||||
if (key !== 'create' || !destination) {
|
||||
if (!destination) {
|
||||
return [];
|
||||
}
|
||||
if (context.category && context.category !== "creation") {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ define(
|
||||
// Update the set of Create actions
|
||||
function refreshActions() {
|
||||
$scope.createActions = $scope.action ?
|
||||
$scope.action.getActions('create') :
|
||||
$scope.action.getActions({ category: "creation" }) :
|
||||
[];
|
||||
}
|
||||
|
||||
|
68
platform/commonUI/browse/src/navigation/BackAction.js
Normal file
68
platform/commonUI/browse/src/navigation/BackAction.js
Normal file
@ -0,0 +1,68 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
/**
|
||||
* Module defining NavigateAction. Created by vwoeltje on 11/10/14.
|
||||
*/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The `back` action navigates to the contextual parent of a
|
||||
* specific domain object.
|
||||
* @memberof platform/commonUI/browse
|
||||
* @constructor
|
||||
* @implements {Action}
|
||||
*/
|
||||
function BackAction(context) {
|
||||
this.domainObject = context.domainObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigate to the object described in the context.
|
||||
* @returns {Promise} a promise that is resolved once the
|
||||
* navigation has been updated
|
||||
*/
|
||||
BackAction.prototype.perform = function () {
|
||||
var parent = this.domainObject.getCapability("context")
|
||||
.getParent();
|
||||
return parent.getCapability("action").perform("navigate");
|
||||
};
|
||||
|
||||
/**
|
||||
* Navigate as an action is only applicable when a domain object
|
||||
* is described in the action context.
|
||||
* @param {ActionContext} context the context in which the action
|
||||
* will be performed
|
||||
* @returns {boolean} true if applicable
|
||||
*/
|
||||
BackAction.appliesTo = function (context) {
|
||||
return context.domainObject !== undefined &&
|
||||
context.domainObject.hasCapability("context");
|
||||
};
|
||||
|
||||
return BackAction;
|
||||
}
|
||||
);
|
@ -53,9 +53,10 @@ define(
|
||||
// based on whether or not we are currently
|
||||
// full screen.
|
||||
var metadata = Object.create(FullscreenAction);
|
||||
metadata.key = "fullscreen";
|
||||
metadata.glyph = screenfull.isFullscreen ? "_" : "z";
|
||||
metadata.description = screenfull.isFullscreen ?
|
||||
EXIT_FULLSCREEN : ENTER_FULLSCREEN;
|
||||
EXIT_FULLSCREEN : ENTER_FULLSCREEN;
|
||||
metadata.group = "windowing";
|
||||
metadata.context = this.context;
|
||||
return metadata;
|
||||
|
@ -49,17 +49,22 @@ define(
|
||||
var expr = attrs[attribute],
|
||||
parsed = $parse(expr);
|
||||
|
||||
// Set the element's scroll to match the scope's state
|
||||
function updateElement(value) {
|
||||
element[0][property] = value;
|
||||
}
|
||||
|
||||
// Handle event; assign to scroll state to scope
|
||||
function updateScope() {
|
||||
parsed.assign(scope, element[0][property]);
|
||||
scope.$apply(expr);
|
||||
}
|
||||
|
||||
// Set the element's scroll to match the scope's state
|
||||
function updateElement(value) {
|
||||
element[0][property] = value;
|
||||
// Some values may be out of range for the scroll bar,
|
||||
// so publish the real scroll value back into scope.
|
||||
if (element[0][property] !== value) {
|
||||
parsed.assign(scope, element[0][property]);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize state in scope
|
||||
parsed.assign(scope, element[0][property]);
|
||||
|
||||
|
Reference in New Issue
Block a user