mirror of
https://github.com/nasa/openmct.git
synced 2025-06-27 03:22:04 +00:00
Compare commits
26 Commits
notebook-a
...
misc-ui-4
Author | SHA1 | Date | |
---|---|---|---|
6db1833a45 | |||
6b1e8862ef | |||
00ce246fc5 | |||
c0c7d96429 | |||
92b2582d0d | |||
4084a1ac86 | |||
8b2edaa6fd | |||
8caeed2ce5 | |||
03be582b54 | |||
1ce84ee56b | |||
cb39ad8500 | |||
cb1a1c2616 | |||
74be02b6de | |||
ce6c1f173e | |||
30a4888363 | |||
b0917a9866 | |||
464e5de947 | |||
47a07da17d | |||
ec4c443299 | |||
3122168b0e | |||
da3af4b3db | |||
850fa28bf6 | |||
270684c5fd | |||
afa1589cb5 | |||
18a94d938f | |||
d026bc2134 |
@ -37,25 +37,25 @@ define([
|
||||
},
|
||||
LIMITS = {
|
||||
rh: {
|
||||
cssClass: "s-limit-upr s-limit-red",
|
||||
cssClass: "is-limit--upr is-limit--red",
|
||||
low: RED,
|
||||
high: Number.POSITIVE_INFINITY,
|
||||
name: "Red High"
|
||||
},
|
||||
rl: {
|
||||
cssClass: "s-limit-lwr s-limit-red",
|
||||
cssClass: "is-limit--lwr is-limit--red",
|
||||
high: -RED,
|
||||
low: Number.NEGATIVE_INFINITY,
|
||||
name: "Red Low"
|
||||
},
|
||||
yh: {
|
||||
cssClass: "s-limit-upr s-limit-yellow",
|
||||
cssClass: "is-limit--upr is-limit--yellow",
|
||||
low: YELLOW,
|
||||
high: RED,
|
||||
name: "Yellow High"
|
||||
},
|
||||
yl: {
|
||||
cssClass: "s-limit-lwr s-limit-yellow",
|
||||
cssClass: "is-limit--lwr is-limit--yellow",
|
||||
low: -RED,
|
||||
high: -YELLOW,
|
||||
name: "Yellow Low"
|
||||
|
@ -79,6 +79,7 @@
|
||||
openmct.install(openmct.plugins.FolderView());
|
||||
openmct.install(openmct.plugins.Tabs());
|
||||
openmct.install(openmct.plugins.FlexibleLayout());
|
||||
openmct.install(openmct.plugins.LADTable());
|
||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
||||
openmct.time.timeSystem('utc');
|
||||
openmct.start();
|
||||
|
@ -32,7 +32,6 @@ define([
|
||||
"./src/actions/SaveAndStopEditingAction",
|
||||
"./src/actions/SaveAsAction",
|
||||
"./src/actions/CancelAction",
|
||||
"./src/policies/EditActionPolicy",
|
||||
"./src/policies/EditPersistableObjectsPolicy",
|
||||
"./src/representers/EditRepresenter",
|
||||
"./src/capabilities/EditorCapability",
|
||||
@ -64,7 +63,6 @@ define([
|
||||
SaveAndStopEditingAction,
|
||||
SaveAsAction,
|
||||
CancelAction,
|
||||
EditActionPolicy,
|
||||
EditPersistableObjectsPolicy,
|
||||
EditRepresenter,
|
||||
EditorCapability,
|
||||
@ -225,10 +223,6 @@ define([
|
||||
}
|
||||
],
|
||||
"policies": [
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": EditActionPolicy
|
||||
},
|
||||
{
|
||||
"category": "action",
|
||||
"implementation": EditPersistableObjectsPolicy,
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Policy controlling when the `edit` and/or `properties` actions
|
||||
* can appear as applicable actions of the `view-control` category
|
||||
* (shown as buttons in the top-right of browse mode.)
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Policy.<Action, ActionContext>}
|
||||
*/
|
||||
function EditActionPolicy(policyService) {
|
||||
this.policyService = policyService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a count of views which are not flagged as non-editable.
|
||||
* @private
|
||||
*/
|
||||
EditActionPolicy.prototype.countEditableViews = function (context) {
|
||||
var domainObject = context.domainObject,
|
||||
count = 0,
|
||||
type, views;
|
||||
|
||||
if (!domainObject) {
|
||||
return count;
|
||||
}
|
||||
|
||||
type = domainObject.getCapability('type');
|
||||
views = domainObject.useCapability('view');
|
||||
|
||||
|
||||
// A view is editable unless explicitly flagged as not
|
||||
(views || []).forEach(function (view) {
|
||||
if (isEditable(view) ||
|
||||
(view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
|
||||
(view.key === 'table' && type.getKey() === 'table') ||
|
||||
(view.key === 'rt-table' && type.getKey() === 'rttable')
|
||||
) {
|
||||
count++;
|
||||
}
|
||||
});
|
||||
|
||||
function isEditable(view) {
|
||||
if (typeof view.editable === Function) {
|
||||
return view.editable(domainObject.useCapability('adapter'));
|
||||
} else {
|
||||
return view.editable === true;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks whether the domain object is currently being edited. If
|
||||
* so, the edit action is not applicable.
|
||||
* @param context
|
||||
* @returns {*|boolean}
|
||||
*/
|
||||
function isEditing(context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject &&
|
||||
domainObject.hasCapability('editor') &&
|
||||
domainObject.getCapability('editor').isEditContextRoot();
|
||||
}
|
||||
|
||||
EditActionPolicy.prototype.allow = function (action, context) {
|
||||
var key = action.getMetadata().key,
|
||||
category = (context || {}).category;
|
||||
|
||||
// Restrict 'edit' to cases where there are editable
|
||||
// views (similarly, restrict 'properties' to when
|
||||
// the converse is true), and where the domain object is not
|
||||
// already being edited.
|
||||
if (key === 'edit') {
|
||||
return this.countEditableViews(context) > 0 && !isEditing(context);
|
||||
} else if (key === 'properties' && category === 'view-control') {
|
||||
return this.countEditableViews(context) < 1 && !isEditing(context);
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
};
|
||||
|
||||
return EditActionPolicy;
|
||||
}
|
||||
);
|
@ -1,49 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Policy controlling which views should be visible in Edit mode.
|
||||
* @memberof platform/commonUI/edit
|
||||
* @constructor
|
||||
* @implements {Policy.<View, DomainObject>}
|
||||
*/
|
||||
function EditableViewPolicy() {
|
||||
}
|
||||
|
||||
EditableViewPolicy.prototype.allow = function (view, domainObject) {
|
||||
// If a view is flagged as non-editable, only allow it
|
||||
// while we're not in Edit mode.
|
||||
if ((view || {}).editable === false) {
|
||||
return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').inEditContext());
|
||||
}
|
||||
|
||||
// Like all policies, allow by default.
|
||||
return true;
|
||||
};
|
||||
|
||||
return EditableViewPolicy;
|
||||
}
|
||||
);
|
@ -1,138 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/policies/EditActionPolicy"],
|
||||
function (EditActionPolicy) {
|
||||
|
||||
describe("The Edit action policy", function () {
|
||||
var editableView,
|
||||
nonEditableView,
|
||||
testViews,
|
||||
testContext,
|
||||
mockDomainObject,
|
||||
mockEditAction,
|
||||
mockPropertiesAction,
|
||||
mockTypeCapability,
|
||||
mockEditorCapability,
|
||||
capabilities,
|
||||
plotView,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
[
|
||||
'useCapability',
|
||||
'hasCapability',
|
||||
'getCapability'
|
||||
]
|
||||
);
|
||||
mockEditorCapability = jasmine.createSpyObj('editorCapability', ['isEditContextRoot']);
|
||||
mockTypeCapability = jasmine.createSpyObj('type', ['getKey']);
|
||||
capabilities = {
|
||||
'editor': mockEditorCapability,
|
||||
'type': mockTypeCapability
|
||||
};
|
||||
|
||||
mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']);
|
||||
mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']);
|
||||
|
||||
mockDomainObject.getCapability.and.callFake(function (capability) {
|
||||
return capabilities[capability];
|
||||
});
|
||||
mockDomainObject.hasCapability.and.callFake(function (capability) {
|
||||
return !!capabilities[capability];
|
||||
});
|
||||
|
||||
editableView = { editable: true };
|
||||
nonEditableView = { editable: false };
|
||||
plotView = { key: "plot", editable: false };
|
||||
testViews = [];
|
||||
|
||||
mockDomainObject.useCapability.and.callFake(function (c) {
|
||||
// Provide test views, only for the view capability
|
||||
return c === 'view' && testViews;
|
||||
});
|
||||
|
||||
mockEditAction.getMetadata.and.returnValue({ key: 'edit' });
|
||||
mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' });
|
||||
|
||||
testContext = {
|
||||
domainObject: mockDomainObject,
|
||||
category: 'view-control'
|
||||
};
|
||||
|
||||
policy = new EditActionPolicy();
|
||||
});
|
||||
|
||||
it("allows the edit action when there are editable views", function () {
|
||||
testViews = [editableView];
|
||||
expect(policy.allow(mockEditAction, testContext)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows the edit properties action when there are no editable views", function () {
|
||||
testViews = [nonEditableView, nonEditableView];
|
||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
|
||||
});
|
||||
|
||||
it("disallows the edit action when there are no editable views", function () {
|
||||
testViews = [nonEditableView, nonEditableView];
|
||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
||||
});
|
||||
|
||||
it("disallows the edit properties action when there are" +
|
||||
" editable views", function () {
|
||||
testViews = [editableView];
|
||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(false);
|
||||
});
|
||||
|
||||
it("disallows the edit action when object is already being" +
|
||||
" edited", function () {
|
||||
testViews = [editableView];
|
||||
mockEditorCapability.isEditContextRoot.and.returnValue(true);
|
||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
||||
});
|
||||
|
||||
it("allows editing of panels in plot view", function () {
|
||||
testViews = [plotView];
|
||||
mockTypeCapability.getKey.and.returnValue('telemetry.panel');
|
||||
|
||||
expect(policy.allow(mockEditAction, testContext)).toBe(true);
|
||||
});
|
||||
|
||||
it("disallows editing of plot view when object not a panel type", function () {
|
||||
testViews = [plotView];
|
||||
mockTypeCapability.getKey.and.returnValue('something.else');
|
||||
|
||||
expect(policy.allow(mockEditAction, testContext)).toBe(false);
|
||||
});
|
||||
|
||||
|
||||
it("allows the edit properties outside of the 'view-control' category", function () {
|
||||
testViews = [nonEditableView];
|
||||
testContext.category = "something-else";
|
||||
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -1,79 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
["../../src/policies/EditableViewPolicy"],
|
||||
function (EditableViewPolicy) {
|
||||
|
||||
describe("The editable view policy", function () {
|
||||
var mockDomainObject,
|
||||
testMode,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
testMode = true; // Act as if we're in Edit mode by default
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['hasCapability', 'getCapability']
|
||||
);
|
||||
mockDomainObject.getCapability.and.returnValue({
|
||||
inEditContext: function () {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
mockDomainObject.hasCapability.and.callFake(function (c) {
|
||||
return (c === 'editor') && testMode;
|
||||
});
|
||||
|
||||
policy = new EditableViewPolicy();
|
||||
});
|
||||
|
||||
it("disallows views in edit mode that are flagged as non-editable", function () {
|
||||
expect(policy.allow({ editable: false }, mockDomainObject))
|
||||
.toBeFalsy();
|
||||
});
|
||||
|
||||
it("allows views in edit mode that are flagged as editable", function () {
|
||||
expect(policy.allow({ editable: true }, mockDomainObject))
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
it("allows any view outside of edit mode", function () {
|
||||
var testViews = [
|
||||
{ editable: false },
|
||||
{ editable: true },
|
||||
{ someKey: "some value" }
|
||||
];
|
||||
testMode = false; // Act as if we're not in Edit mode
|
||||
|
||||
testViews.forEach(function (testView) {
|
||||
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it("treats views with no defined 'editable' property as editable", function () {
|
||||
expect(policy.allow({ someKey: "some value" }, mockDomainObject))
|
||||
.toBeTruthy();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
@ -19,16 +19,14 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="l-time-display l-digital l-clock s-clock" ng-controller="ClockController as clock">
|
||||
<div class="l-elem-wrapper">
|
||||
<span class="l-elem timezone">
|
||||
{{clock.zone()}}
|
||||
</span>
|
||||
<span class="l-elem value active">
|
||||
{{clock.text()}}
|
||||
</span>
|
||||
<span class="l-elem ampm">
|
||||
{{clock.ampm()}}
|
||||
</span>
|
||||
<div class="c-clock l-time-display" ng-controller="ClockController as clock">
|
||||
<div class="c-clock__timezone">
|
||||
{{clock.zone()}}
|
||||
</div>
|
||||
<div class="c-clock__value">
|
||||
{{clock.text()}}
|
||||
</div>
|
||||
<div class="c-clock__ampm">
|
||||
{{clock.ampm()}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,21 +19,19 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="l-time-display l-digital l-timer s-timer s-state-{{timer.timerState}}" ng-controller="TimerController as timer">
|
||||
<div class="l-elem-wrapper l-flex-row">
|
||||
<div class="l-elem-wrapper l-flex-row controls">
|
||||
<a ng-click="timer.clickStopButton()"
|
||||
title="Stop"
|
||||
class="flex-elem s-icon-button t-btn-stop icon-box"></a>
|
||||
<a ng-click="timer.clickButton()"
|
||||
title="{{timer.buttonText()}}"
|
||||
class="flex-elem s-icon-button t-btn-pauseplay {{timer.buttonCssClass()}}"></a>
|
||||
</div>
|
||||
<span class="flex-elem l-value {{timer.signClass()}}">
|
||||
<span class="value"
|
||||
ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}}
|
||||
</span>
|
||||
</span>
|
||||
<span ng-controller="RefreshingController"></span>
|
||||
<div class="c-timer is-{{timer.timerState}}" ng-controller="TimerController as timer">
|
||||
<div class="c-timer__controls">
|
||||
<button ng-click="timer.clickStopButton()"
|
||||
ng-hide="timer.timerState == 'stopped'"
|
||||
title="Reset"
|
||||
class="c-timer__ctrl-reset c-click-icon c-click-icon--major icon-reset"></button>
|
||||
<button ng-click="timer.clickButton()"
|
||||
title="{{timer.buttonText()}}"
|
||||
class="c-timer__ctrl-pause-play c-click-icon c-click-icon--major {{timer.buttonCssClass()}}"></button>
|
||||
</div>
|
||||
<div class="c-timer__direction {{timer.signClass()}}"
|
||||
ng-hide="!timer.signClass()"></div>
|
||||
<div class="c-timer__value">{{timer.text() || "--:--:--"}}
|
||||
</div>
|
||||
<span class="c-timer__ng-controller u-contents" ng-controller="RefreshingController"></span>
|
||||
</div>
|
||||
|
@ -30,6 +30,7 @@ define([
|
||||
"./src/controllers/CompositeController",
|
||||
"./src/controllers/ColorController",
|
||||
"./src/controllers/DialogButtonController",
|
||||
"./src/controllers/SnapshotPreviewController",
|
||||
"./res/templates/controls/autocomplete.html",
|
||||
"./res/templates/controls/checkbox.html",
|
||||
"./res/templates/controls/datetime.html",
|
||||
@ -44,6 +45,7 @@ define([
|
||||
"./res/templates/controls/dialog.html",
|
||||
"./res/templates/controls/radio.html",
|
||||
"./res/templates/controls/file-input.html",
|
||||
"./res/templates/controls/snap-view.html",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
MCTForm,
|
||||
@ -55,6 +57,7 @@ define([
|
||||
CompositeController,
|
||||
ColorController,
|
||||
DialogButtonController,
|
||||
SnapshotPreviewController,
|
||||
autocompleteTemplate,
|
||||
checkboxTemplate,
|
||||
datetimeTemplate,
|
||||
@ -69,6 +72,7 @@ define([
|
||||
dialogTemplate,
|
||||
radioTemplate,
|
||||
fileInputTemplate,
|
||||
snapViewTemplate,
|
||||
legacyRegistry
|
||||
) {
|
||||
|
||||
@ -153,6 +157,10 @@ define([
|
||||
{
|
||||
"key": "file-input",
|
||||
"template": fileInputTemplate
|
||||
},
|
||||
{
|
||||
"key": "snap-view",
|
||||
"template": snapViewTemplate
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
@ -186,6 +194,14 @@ define([
|
||||
"$scope",
|
||||
"dialogService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "SnapshotPreviewController",
|
||||
"implementation": SnapshotPreviewController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"openmct"
|
||||
]
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
|
@ -1,5 +1,5 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
@ -19,11 +19,18 @@
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class='form-control select' ng-controller="selectSnapshotController">
|
||||
<select
|
||||
ng-model="selectModel"
|
||||
ng-options="opt.value as opt.name for opt in options"
|
||||
ng-required="ngRequired"
|
||||
name="mctControl">
|
||||
</select>
|
||||
</div>
|
||||
<span ng-controller="SnapshotPreviewController"
|
||||
class='form-control shell'>
|
||||
<span class='field control {{structure.cssClass}}'>
|
||||
<image
|
||||
class="c-ne__embed__snap-thumb"
|
||||
src="{{imageUrl || structure.src}}"
|
||||
ng-click="previewImage(imageUrl || structure.src)"
|
||||
name="mctControl">
|
||||
</image>
|
||||
<br>
|
||||
<a title="Annotate" class="s-button icon-pencil" ng-click="annotateImage(ngModel, field, imageUrl || structure.src)">
|
||||
<span class="title-label">Annotate</span>
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
120
platform/forms/src/controllers/SnapshotPreviewController.js
Normal file
120
platform/forms/src/controllers/SnapshotPreviewController.js
Normal file
@ -0,0 +1,120 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
[
|
||||
'painterro'
|
||||
],
|
||||
function (Painterro) {
|
||||
|
||||
function SnapshotPreviewController($scope, openmct) {
|
||||
|
||||
$scope.previewImage = function (imageUrl) {
|
||||
var image = document.createElement('img');
|
||||
image.src = imageUrl;
|
||||
|
||||
openmct.overlays.overlay(
|
||||
{
|
||||
element: image,
|
||||
size: 'large'
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
$scope.annotateImage = function (ngModel, field, imageUrl) {
|
||||
$scope.imageUrl = imageUrl;
|
||||
|
||||
var div = document.createElement('div'),
|
||||
painterroInstance = {},
|
||||
save = false;
|
||||
|
||||
div.id = 'snap-annotation';
|
||||
|
||||
openmct.overlays.overlay(
|
||||
{
|
||||
element: div,
|
||||
size: 'large',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: function () {
|
||||
save = false;
|
||||
painterroInstance.save();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Save',
|
||||
callback: function () {
|
||||
save = true;
|
||||
painterroInstance.save();
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
|
||||
painterroInstance = Painterro({
|
||||
id: 'snap-annotation',
|
||||
activeColor: '#ff0000',
|
||||
activeColorAlpha: 1.0,
|
||||
activeFillColor: '#fff',
|
||||
activeFillColorAlpha: 0.0,
|
||||
backgroundFillColor: '#000',
|
||||
backgroundFillColorAlpha: 0.0,
|
||||
defaultFontSize: 16,
|
||||
defaultLineWidth: 2,
|
||||
defaultTool: 'ellipse',
|
||||
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
||||
translation: {
|
||||
name: 'en',
|
||||
strings: {
|
||||
lineColor: 'Line',
|
||||
fillColor: 'Fill',
|
||||
lineWidth: 'Size',
|
||||
textColor: 'Color',
|
||||
fontSize: 'Size',
|
||||
fontStyle: 'Style'
|
||||
}
|
||||
},
|
||||
saveHandler: function (image, done) {
|
||||
if (save) {
|
||||
var url = image.asBlob(),
|
||||
reader = new window.FileReader();
|
||||
|
||||
reader.readAsDataURL(url);
|
||||
reader.onloadend = function () {
|
||||
$scope.imageUrl = reader.result;
|
||||
ngModel[field] = reader.result;
|
||||
};
|
||||
} else {
|
||||
ngModel.field = imageUrl;
|
||||
console.warn('You cancelled the annotation!!!');
|
||||
}
|
||||
done(true);
|
||||
}
|
||||
}).show(imageUrl);
|
||||
};
|
||||
}
|
||||
|
||||
return SnapshotPreviewController;
|
||||
}
|
||||
);
|
@ -40,9 +40,10 @@ define([
|
||||
'../platform/framework/src/Main',
|
||||
'./styles-new/core.scss',
|
||||
'./styles-new/notebook.scss',
|
||||
'./ui/components/layout/Layout.vue',
|
||||
'./ui/layout/Layout.vue',
|
||||
'../platform/core/src/objects/DomainObjectImpl',
|
||||
'../platform/core/src/capabilities/ContextualDomainObject',
|
||||
'./ui/preview/plugin',
|
||||
'vue'
|
||||
], function (
|
||||
EventEmitter,
|
||||
@ -67,6 +68,7 @@ define([
|
||||
Layout,
|
||||
DomainObjectImpl,
|
||||
ContextualDomainObject,
|
||||
PreviewPlugin,
|
||||
Vue
|
||||
) {
|
||||
/**
|
||||
@ -230,7 +232,7 @@ define([
|
||||
this.install(this.plugins.Plot());
|
||||
this.install(this.plugins.TelemetryTable());
|
||||
this.install(this.plugins.DisplayLayout());
|
||||
this.install(this.plugins.Preview());
|
||||
this.install(PreviewPlugin.default());
|
||||
|
||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||
|
@ -58,11 +58,8 @@ define([
|
||||
|
||||
handleLegacyMutation = function (legacyObject) {
|
||||
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
|
||||
|
||||
//Don't trigger self
|
||||
this.eventEmitter.off('mutation', handleMutation);
|
||||
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
|
||||
this.eventEmitter.on('mutation', handleMutation);
|
||||
this.eventEmitter.emit('mutation', newStyleObject);
|
||||
}.bind(this);
|
||||
|
||||
this.eventEmitter.on('mutation', handleMutation);
|
||||
|
@ -21,7 +21,9 @@ define([
|
||||
name: legacyView.name,
|
||||
cssClass: legacyView.cssClass,
|
||||
description: legacyView.description,
|
||||
editable: legacyView.editable,
|
||||
canEdit: function () {
|
||||
return legacyView.editable === true;
|
||||
},
|
||||
canView: function (domainObject) {
|
||||
if (!domainObject || !domainObject.identifier) {
|
||||
return false;
|
||||
|
@ -28,6 +28,11 @@ export default class Editor extends EventEmitter {
|
||||
super();
|
||||
this.editing = false;
|
||||
this.openmct = openmct;
|
||||
document.addEventListener('drop', (event) => {
|
||||
if (!this.isEditing()) {
|
||||
this.edit();
|
||||
}
|
||||
}, {capture: true});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -46,6 +46,7 @@ define([
|
||||
function DefaultCompositionProvider(publicAPI, compositionAPI) {
|
||||
this.publicAPI = publicAPI;
|
||||
this.listeningTo = {};
|
||||
this.onMutation = this.onMutation.bind(this);
|
||||
|
||||
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
||||
this.cannotContainItself = this.cannotContainItself.bind(this);
|
||||
@ -208,9 +209,10 @@ define([
|
||||
if (this.topicListener) {
|
||||
return;
|
||||
}
|
||||
var topic = this.publicAPI.$injector.get('topic');
|
||||
var mutation = topic('mutation');
|
||||
this.topicListener = mutation.listen(this.onMutation.bind(this));
|
||||
this.publicAPI.objects.eventEmitter.on('mutation', this.onMutation);
|
||||
this.topicListener = () => {
|
||||
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation)
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@ -220,7 +222,7 @@ define([
|
||||
* @private
|
||||
*/
|
||||
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
|
||||
var id = oldDomainObject.getId();
|
||||
var id = objectUtils.makeKeyString(oldDomainObject.identifier);
|
||||
var listeners = this.listeningTo[id];
|
||||
|
||||
if (!listeners) {
|
||||
@ -228,7 +230,7 @@ define([
|
||||
}
|
||||
|
||||
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
||||
var newComposition = oldDomainObject.getModel().composition.map(objectUtils.makeKeyString);
|
||||
var newComposition = oldDomainObject.composition.map(objectUtils.makeKeyString);
|
||||
|
||||
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
||||
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
||||
|
@ -83,18 +83,15 @@ define([
|
||||
this.object = newObject;
|
||||
}.bind(this);
|
||||
|
||||
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||
|
||||
//Emit event specific to property
|
||||
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
||||
|
||||
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||
|
||||
//Emit wildcare event
|
||||
//Emit wildcard event
|
||||
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
|
||||
|
||||
//Emit a general "any object" event
|
||||
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
|
||||
|
||||
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||
//Emit event specific to property
|
||||
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
||||
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||
};
|
||||
|
||||
return MutableObject;
|
||||
|
@ -1,4 +1,4 @@
|
||||
import ProgressComponent from '../../ui/components/layout/ProgressBar.vue';
|
||||
import ProgressComponent from '../../ui/components/ProgressBar.vue';
|
||||
import Overlay from './Overlay';
|
||||
import Vue from 'vue';
|
||||
|
||||
|
@ -20,47 +20,48 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
define([
|
||||
'vue',
|
||||
'../../res/templates/viewSnapshot.html'
|
||||
'./components/LadTableSet.vue',
|
||||
'vue'
|
||||
], function (
|
||||
Vue,
|
||||
snapshotOverlayTemplate
|
||||
LadTableSet,
|
||||
Vue
|
||||
) {
|
||||
function SnapshotOverlay (embedObject, formatTime) {
|
||||
this.embedObject = embedObject;
|
||||
function LADTableSetViewProvider(openmct) {
|
||||
return {
|
||||
key: 'LadTableSet',
|
||||
name: 'LAD Table Set',
|
||||
cssClass: 'icon-tabular-lad-set',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'LadTableSet';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
this.snapshotOverlayVue = new Vue({
|
||||
template: snapshotOverlayTemplate,
|
||||
data: function () {
|
||||
return {
|
||||
embed: embedObject
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
components: {
|
||||
LadTableSet: LadTableSet.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-set></lad-table-set>'
|
||||
});
|
||||
},
|
||||
destroy: function (element) {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
close: this.close.bind(this),
|
||||
formatTime: formatTime
|
||||
priority: function () {
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
|
||||
this.open();
|
||||
};
|
||||
}
|
||||
|
||||
SnapshotOverlay.prototype.open = function () {
|
||||
this.overlay = document.createElement('div');
|
||||
this.overlay.classList.add('abs');
|
||||
|
||||
document.body.appendChild(this.overlay);
|
||||
|
||||
this.overlay.appendChild(this.snapshotOverlayVue.$mount().$el);
|
||||
};
|
||||
|
||||
SnapshotOverlay.prototype.close = function (event) {
|
||||
event.stopPropagation();
|
||||
this.snapshotOverlayVue.$destroy();
|
||||
this.overlay.parentNode.removeChild(this.overlay);
|
||||
};
|
||||
|
||||
return SnapshotOverlay;
|
||||
return LADTableSetViewProvider;
|
||||
});
|
67
src/plugins/LADTable/LADTableViewProvider.js
Normal file
67
src/plugins/LADTable/LADTableViewProvider.js
Normal file
@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
'./components/LadTable.vue',
|
||||
'vue'
|
||||
], function (
|
||||
LadTableComponent,
|
||||
Vue
|
||||
) {
|
||||
function LADTableViewProvider(openmct) {
|
||||
return {
|
||||
key: 'LadTable',
|
||||
name: 'LAD Table',
|
||||
cssClass: 'icon-tabular-lad',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'LadTable';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
components: {
|
||||
LadTableComponent: LadTableComponent.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-component></lad-table-component>'
|
||||
});
|
||||
},
|
||||
destroy: function (element) {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
priority: function () {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
return LADTableViewProvider;
|
||||
});
|
120
src/plugins/LADTable/components/LADRow.vue
Normal file
120
src/plugins/LADTable/components/LADRow.vue
Normal file
@ -0,0 +1,120 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<tr>
|
||||
<td>{{name}}</td>
|
||||
<td>{{timestamp}}</td>
|
||||
<td :class="valueClass">
|
||||
{{value}}
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: ['domainObject'],
|
||||
data() {
|
||||
return {
|
||||
name: this.domainObject.name,
|
||||
timestamp: '---',
|
||||
value: '---',
|
||||
valueClass: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
updateValues(datum) {
|
||||
this.timestamp = this.formats[this.timestampKey].format(datum);
|
||||
this.value = this.formats[this.valueKey].format(datum);
|
||||
|
||||
var limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
|
||||
|
||||
if (limit) {
|
||||
this.valueClass = limit.cssClass;
|
||||
} else {
|
||||
this.valueClass = '';
|
||||
}
|
||||
},
|
||||
updateName(name){
|
||||
this.name = name;
|
||||
},
|
||||
updateTimeSystem(timeSystem) {
|
||||
this.value = '---';
|
||||
this.timestamp = '---';
|
||||
this.valueClass = '';
|
||||
this.timestampKey = timeSystem.key;
|
||||
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(this.domainObject, {strategy: 'latest'})
|
||||
.then((array) => this.updateValues(array[array.length - 1]));
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
|
||||
this.limitEvaluator = openmct
|
||||
.telemetry
|
||||
.limitEvaluator(this.domainObject);
|
||||
|
||||
this.stopWatchingMutation = openmct
|
||||
.objects
|
||||
.observe(
|
||||
this.domainObject,
|
||||
'*',
|
||||
this.updateName
|
||||
);
|
||||
|
||||
this.openmct.time.on('timeSystem', this.updateTimeSystem);
|
||||
|
||||
this.timestampKey = this.openmct.time.timeSystem().key;
|
||||
|
||||
this.valueMetadata = this
|
||||
.metadata
|
||||
.valuesForHints(['range'])[0];
|
||||
|
||||
this.valueKey = this.valueMetadata.key
|
||||
|
||||
this.unsubscribe = this.openmct
|
||||
.telemetry
|
||||
.subscribe(this.domainObject, this.updateValues);
|
||||
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(this.domainObject, {strategy: 'latest'})
|
||||
.then((array) => this.updateValues(array[array.length - 1]));
|
||||
},
|
||||
destroyed() {
|
||||
this.stopWatchingMutation();
|
||||
this.unsubscribe();
|
||||
this.openmct.off('timeSystem', this.updateTimeSystem);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
82
src/plugins/LADTable/components/LADTable.vue
Normal file
82
src/plugins/LADTable/components/LADTable.vue
Normal file
@ -0,0 +1,82 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<table class="c-table c-lad-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Timestamp</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<lad-row
|
||||
v-for="item in items"
|
||||
:key="item.key"
|
||||
:domainObject="item.domainObject">
|
||||
</lad-row>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import lodash from 'lodash';
|
||||
import LadRow from './LadRow.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
components: {
|
||||
LadRow
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
items: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addItem(domainObject) {
|
||||
let item = {};
|
||||
item.domainObject = domainObject;
|
||||
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
this.items.push(item);
|
||||
},
|
||||
removeItem(identifier) {
|
||||
let index = _.findIndex(this.items, (item) => this.openmct.objects.makeKeyString(identifier) === item.key);
|
||||
|
||||
this.items.splice(index, 1);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
135
src/plugins/LADTable/components/LadTableSet.vue
Normal file
135
src/plugins/LADTable/components/LadTableSet.vue
Normal file
@ -0,0 +1,135 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<table class="c-table c-lad-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Timestamp</th>
|
||||
<th>Value</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<template
|
||||
v-for="primary in primaryTelemetryObjects">
|
||||
<tr class="c-table__group-header"
|
||||
:key="primary.key">
|
||||
<td colspan="10">{{primary.domainObject.name}}</td>
|
||||
</tr>
|
||||
<lad-row
|
||||
v-for="secondary in secondaryTelemetryObjects[primary.key]"
|
||||
:key="secondary.key"
|
||||
:domainObject="secondary.domainObject">
|
||||
</lad-row>
|
||||
</template>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import lodash from 'lodash';
|
||||
import LadRow from './LadRow.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
components: {
|
||||
LadRow
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
primaryTelemetryObjects: [],
|
||||
secondaryTelemetryObjects: {},
|
||||
compositions: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addPrimary(domainObject) {
|
||||
let primary = {};
|
||||
primary.domainObject = domainObject;
|
||||
primary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, []);
|
||||
this.primaryTelemetryObjects.push(primary);
|
||||
|
||||
let composition = openmct.composition.get(primary.domainObject),
|
||||
addCallback = this.addSecondary(primary),
|
||||
removeCallback = this.removeSecondary(primary);
|
||||
|
||||
composition.on('add', addCallback);
|
||||
composition.on('remove', removeCallback);
|
||||
composition.load();
|
||||
|
||||
this.compositions.push({composition, addCallback, removeCallback});
|
||||
},
|
||||
removePrimary(identifier) {
|
||||
let index = _.findIndex(this.primaryTelemetryObjects, (primary) => this.openmct.objects.makeKeyString(identifier) === primary.key),
|
||||
primary = this.primaryTelemetryObjects[index];
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
|
||||
this.primaryTelemetryObjects.splice(index,1);
|
||||
primary = undefined;
|
||||
},
|
||||
addSecondary(primary) {
|
||||
return (domainObject) => {
|
||||
let secondary = {};
|
||||
secondary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
secondary.domainObject = domainObject;
|
||||
|
||||
let array = this.secondaryTelemetryObjects[primary.key];
|
||||
array.push(secondary);
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, array);
|
||||
}
|
||||
},
|
||||
removeSecondary(primary) {
|
||||
return (identifier) => {
|
||||
let array = this.secondaryTelemetryObjects[primary.key],
|
||||
index = _.findIndex(array, (secondary) => this.openmct.objects.makeKeyString(identifier) === secondary.key);
|
||||
|
||||
array.splice(index, 1);
|
||||
|
||||
this.$set(this.secondaryTelemetryObjects, primary.key, array);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addPrimary);
|
||||
this.composition.on('remove', this.removePrimary);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addPrimary);
|
||||
this.composition.off('remove', this.removePrimary);
|
||||
this.compositions.forEach(c => {
|
||||
c.composition.off('add', c.addCallback);
|
||||
c.composition.off('remove', c.removeCallback);
|
||||
});
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
56
src/plugins/LADTable/plugin.js
Normal file
56
src/plugins/LADTable/plugin.js
Normal file
@ -0,0 +1,56 @@
|
||||
/*****************************************************************************
|
||||
* 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([
|
||||
'./LADTableViewProvider',
|
||||
'./LADTableSetViewProvider'
|
||||
], function (
|
||||
LADTableViewProvider,
|
||||
LADTableSetViewProvider
|
||||
) {
|
||||
return function plugin() {
|
||||
return function install(openmct) {
|
||||
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
|
||||
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
|
||||
|
||||
openmct.types.addType('LadTable', {
|
||||
name: "LAD Table",
|
||||
creatable: true,
|
||||
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
|
||||
cssClass: 'icon-tabular-lad',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
}
|
||||
});
|
||||
|
||||
openmct.types.addType('LadTableSet', {
|
||||
name: "LAD Table Set",
|
||||
creatable: true,
|
||||
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
|
||||
cssClass: 'icon-tabular-lad-set',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
@ -125,11 +125,41 @@ define([], function () {
|
||||
let separator = {
|
||||
control: "separator"
|
||||
};
|
||||
let remove = {
|
||||
control: "button",
|
||||
domainObject: selectedParent,
|
||||
icon: "icon-trash",
|
||||
title: "Delete the selected object",
|
||||
method: function () {
|
||||
let removeItem = selection[1].context.removeItem;
|
||||
let prompt = openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: `Warning! This action will remove this item from the Display Layout. Do you want to continue?`,
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
emphasis: 'true',
|
||||
callback: function () {
|
||||
removeItem(layoutItem, layoutItemIndex);
|
||||
prompt.dismiss();
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Cancel',
|
||||
callback: function () {
|
||||
prompt.dismiss();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (layoutItem.type === 'subobject-view') {
|
||||
if (toolbar.length > 0) {
|
||||
toolbar.push(separator);
|
||||
}
|
||||
|
||||
toolbar.push({
|
||||
control: "toggle-button",
|
||||
domainObject: selectedParent,
|
||||
@ -147,6 +177,8 @@ define([], function () {
|
||||
}
|
||||
]
|
||||
});
|
||||
toolbar.push(separator);
|
||||
toolbar.push(remove);
|
||||
} else {
|
||||
const TEXT_SIZE = [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96];
|
||||
let fill = {
|
||||
@ -263,7 +295,9 @@ define([], function () {
|
||||
x,
|
||||
y,
|
||||
height,
|
||||
width
|
||||
width,
|
||||
separator,
|
||||
remove
|
||||
];
|
||||
} else if (layoutItem.type === 'text-view' ) {
|
||||
let text = {
|
||||
@ -286,7 +320,9 @@ define([], function () {
|
||||
height,
|
||||
width,
|
||||
separator,
|
||||
text
|
||||
text,
|
||||
separator,
|
||||
remove
|
||||
];
|
||||
} else if (layoutItem.type === 'box-view') {
|
||||
toolbar = [
|
||||
@ -296,7 +332,9 @@ define([], function () {
|
||||
x,
|
||||
y,
|
||||
height,
|
||||
width
|
||||
width,
|
||||
separator,
|
||||
remove
|
||||
];
|
||||
} else if (layoutItem.type === 'image-view') {
|
||||
let url = {
|
||||
@ -315,7 +353,9 @@ define([], function () {
|
||||
height,
|
||||
width,
|
||||
separator,
|
||||
url
|
||||
url,
|
||||
separator,
|
||||
remove
|
||||
];
|
||||
} else if (layoutItem.type === 'line-view') {
|
||||
let x2 = {
|
||||
@ -340,7 +380,9 @@ define([], function () {
|
||||
x,
|
||||
y,
|
||||
x2,
|
||||
y2
|
||||
y2,
|
||||
separator,
|
||||
remove
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -75,16 +75,22 @@
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el,
|
||||
context,
|
||||
this.initSelect
|
||||
);
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
|
@ -40,6 +40,7 @@
|
||||
<component v-for="(item, index) in layoutItems"
|
||||
:is="item.type"
|
||||
:item="item"
|
||||
:key="item.id"
|
||||
:gridSize="gridSize"
|
||||
:initSelect="initSelectIndex === index"
|
||||
:index="index"
|
||||
@ -76,7 +77,7 @@
|
||||
.l-shell__main-container {
|
||||
> .l-layout {
|
||||
[s-selected] {
|
||||
border: $browseBorderSelected;
|
||||
border: $browseSelectedBorder;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -176,13 +177,13 @@
|
||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||
},
|
||||
handleDrop($event) {
|
||||
if (!$event.dataTransfer.types.includes('domainobject')) {
|
||||
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$event.preventDefault();
|
||||
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('domainobject'));
|
||||
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||
let elementRect = this.$el.getBoundingClientRect();
|
||||
let droppedObjectPosition = [
|
||||
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
||||
@ -226,6 +227,7 @@
|
||||
addItem(itemType, ...options) {
|
||||
let item = getItemDefinition(itemType, this.openmct, this.gridSize, ...options);
|
||||
item.type = itemType;
|
||||
item.id = uuid();
|
||||
this.trackItem(item);
|
||||
this.layoutItems.push(item);
|
||||
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
|
||||
@ -233,11 +235,46 @@
|
||||
},
|
||||
trackItem(item) {
|
||||
if (item.type === "telemetry-view") {
|
||||
this.telemetryViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
let count = this.telemetryViewMap[keyString] || 0;
|
||||
this.telemetryViewMap[keyString] = ++count;
|
||||
} else if (item.type === "subobject-view") {
|
||||
this.objectViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
|
||||
}
|
||||
},
|
||||
removeItem(item, index) {
|
||||
this.initSelectIndex = -1;
|
||||
this.layoutItems.splice(index, 1);
|
||||
this.mutate("configuration.items", this.layoutItems);
|
||||
this.untrackItem(item);
|
||||
this.$el.click();
|
||||
},
|
||||
untrackItem(item) {
|
||||
if (!item.identifier) {
|
||||
return;
|
||||
}
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||
|
||||
if (item.type === 'telemetry-view') {
|
||||
let count = --this.telemetryViewMap[keyString];
|
||||
|
||||
if (count === 0) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
} else if (item.type === 'subobject-view') {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromComposition(keyString);
|
||||
}
|
||||
},
|
||||
removeFromComposition(keyString) {
|
||||
let composition = _.get(this.internalDomainObject, 'composition');
|
||||
composition = composition.filter(identifier => {
|
||||
return this.openmct.objects.makeKeyString(identifier) !== keyString;
|
||||
});
|
||||
this.mutate("composition", composition);
|
||||
},
|
||||
initializeItems() {
|
||||
this.telemetryViewMap = {};
|
||||
this.objectViewMap = {};
|
||||
@ -254,7 +291,26 @@
|
||||
}
|
||||
},
|
||||
removeChild(identifier) {
|
||||
// TODO: implement
|
||||
let keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
|
||||
if (this.objectViewMap[keyString]) {
|
||||
delete this.objectViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
} else if (this.telemetryViewMap[keyString]) {
|
||||
delete this.telemetryViewMap[keyString];
|
||||
this.removeFromConfiguration(keyString);
|
||||
}
|
||||
},
|
||||
removeFromConfiguration(keyString) {
|
||||
let layoutItems = this.layoutItems.filter(item => {
|
||||
if (!item.identifier) {
|
||||
return true;
|
||||
} else {
|
||||
return this.openmct.objects.makeKeyString(item.identifier) !== keyString;
|
||||
}
|
||||
});
|
||||
this.mutate("configuration.items", layoutItems);
|
||||
this.$el.click();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -77,13 +77,22 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, context, this.initSelect);
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
|
@ -21,7 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout__frame c-frame has-local-controls"
|
||||
<div class="l-layout__frame c-frame"
|
||||
:class="{
|
||||
'no-frame': !item.hasFrame,
|
||||
'u-inspectable': inspectable,
|
||||
|
@ -21,10 +21,9 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="l-layout__frame c-frame has-local-controls no-frame"
|
||||
<div class="l-layout__frame c-frame no-frame"
|
||||
:style="style">
|
||||
<svg width="100%"
|
||||
height="100%">
|
||||
<svg width="100%" height="100%">
|
||||
<line v-bind="linePosition"
|
||||
:stroke="item.stroke"
|
||||
stroke-width="2">
|
||||
@ -101,9 +100,6 @@
|
||||
top: `${top}px`,
|
||||
width: `${width}px`,
|
||||
height: `${height}px`,
|
||||
minWidth: `${width}px`,
|
||||
minHeight: `${height}px`,
|
||||
position: 'absolute'
|
||||
};
|
||||
},
|
||||
startHandleClass() {
|
||||
@ -210,17 +206,22 @@
|
||||
return dragPosition;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el,
|
||||
context,
|
||||
this.initSelect
|
||||
);
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
|
@ -24,90 +24,16 @@
|
||||
:grid-size="gridSize"
|
||||
@endDrag="(item, updates) => $emit('endDrag', item, updates)"
|
||||
@drilledIn="item => $emit('drilledIn', item)">
|
||||
<div class="u-contents">
|
||||
<div class="c-so-view__header">
|
||||
<div class="c-so-view__header__start">
|
||||
<div class="c-so-view__header__name"
|
||||
:class="cssClass">
|
||||
{{ domainObject && domainObject.name }}
|
||||
</div>
|
||||
<context-menu-drop-down
|
||||
:object-path="objectPath">
|
||||
</context-menu-drop-down>
|
||||
</div>
|
||||
<div class="c-so-view__header__end">
|
||||
<div class="c-button icon-expand local-controls--hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
<object-view class="c-so-view__object-view"
|
||||
:object="domainObject"></object-view>
|
||||
</div>
|
||||
<object-frame v-if="domainObject"
|
||||
:domain-object="domainObject"
|
||||
:object-path="objectPath"
|
||||
:has-frame="item.hasFrame">
|
||||
</object-frame>
|
||||
</layout-frame>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-so-view {
|
||||
/*************************** HEADER */
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__start,
|
||||
&__end {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__name {
|
||||
@include headerFont(1em);
|
||||
display: flex;
|
||||
&:before {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
.no-frame & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
@include ellipsize();
|
||||
@include headerFont(1.2em);
|
||||
flex: 0 1 auto;
|
||||
|
||||
&:before {
|
||||
// Object type icon
|
||||
flex: 0 0 auto;
|
||||
margin-right: $interiorMarginSm;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************** OBJECT VIEW */
|
||||
&__object-view {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
|
||||
.c-object-view {
|
||||
.u-fills-container {
|
||||
// Expand component types that fill a container
|
||||
@include abs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ObjectView from '../../../ui/components/layout/ObjectView.vue'
|
||||
import ContextMenuDropDown from '../../../ui/components/controls/contextMenuDropDown.vue';
|
||||
import ObjectFrame from '../../../ui/components/ObjectFrame.vue'
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
|
||||
const MINIMUM_FRAME_SIZE = [320, 180],
|
||||
@ -152,27 +78,33 @@
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
cssClass: undefined,
|
||||
objectPath: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ObjectView,
|
||||
ContextMenuDropDown,
|
||||
ObjectFrame,
|
||||
LayoutFrame
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = [this.domainObject].concat(this.openmct.router.path);
|
||||
this.cssClass = this.openmct.types.get(this.domainObject.type).definition.cssClass;
|
||||
let context = {
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, context, this.initSelect);
|
||||
this.$el, this.context, this.initSelect);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -160,6 +160,15 @@
|
||||
domainObject: undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
requestHistoricalData() {
|
||||
let bounds = this.openmct.time.bounds();
|
||||
@ -205,13 +214,13 @@
|
||||
this.requestHistoricalData();
|
||||
this.subscribeToObject();
|
||||
|
||||
let context = {
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, context, this.initSelect);
|
||||
this.$el, this.context, this.initSelect);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
@ -82,13 +82,22 @@
|
||||
};
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
index(newIndex) {
|
||||
if (!this.context) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let context = {
|
||||
this.context = {
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, context, this.initSelect);
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
destroyed() {
|
||||
if (this.removeSelectable) {
|
||||
|
@ -33,6 +33,9 @@ export default function () {
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
return {
|
||||
@ -57,7 +60,8 @@ export default function () {
|
||||
getSelectionContext() {
|
||||
return {
|
||||
item: domainObject,
|
||||
addElement: component && component.$refs.displayLayout.addElement
|
||||
addElement: component && component.$refs.displayLayout.addElement,
|
||||
removeItem: component && component.$refs.displayLayout.removeItem
|
||||
}
|
||||
},
|
||||
destroy() {
|
||||
|
@ -100,7 +100,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
allowDrop(event, index) {
|
||||
if (event.dataTransfer.getData('domainObject')) {
|
||||
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
return true;
|
||||
}
|
||||
let frameId = event.dataTransfer.getData('frameid'),
|
||||
@ -124,9 +124,9 @@ export default {
|
||||
}
|
||||
},
|
||||
moveOrCreateFrame(insertIndex, event) {
|
||||
if (event.dataTransfer.types.includes('domainobject')) {
|
||||
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
// create frame using domain object
|
||||
let domainObject = JSON.parse(event.dataTransfer.getData('domainObject'));
|
||||
let domainObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||
this.$emit(
|
||||
'create-frame',
|
||||
this.index,
|
||||
|
@ -21,8 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div v-if="isEditing"
|
||||
v-show="isValidTarget">
|
||||
<div v-show="isValidTarget">
|
||||
<div class="c-drop-hint c-drop-hint--always-show"
|
||||
:class="{'is-mouse-over': isMouseOver}"
|
||||
@dragenter="dragenter"
|
||||
@ -37,8 +36,6 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import isEditingMixin from '../mixins/isEditing';
|
||||
|
||||
export default {
|
||||
props:{
|
||||
index: Number,
|
||||
@ -47,7 +44,6 @@ export default {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
mixins: [isEditingMixin],
|
||||
data() {
|
||||
return {
|
||||
isMouseOver: false,
|
||||
|
@ -27,15 +27,16 @@
|
||||
}">
|
||||
|
||||
<div class="c-frame c-fl-frame__drag-wrapper is-selectable is-moveable"
|
||||
:class="{'no-frame': noFrame}"
|
||||
draggable="true"
|
||||
@dragstart="initDrag"
|
||||
ref="frame">
|
||||
|
||||
<subobject-view
|
||||
v-if="item.domainObject.identifier"
|
||||
:item="item">
|
||||
</subobject-view>
|
||||
<object-frame
|
||||
v-if="domainObject"
|
||||
:domain-object="domainObject"
|
||||
:object-path="objectPath"
|
||||
:has-frame="hasFrame">
|
||||
</object-frame>
|
||||
|
||||
<div class="c-fl-frame__size-indicator"
|
||||
v-if="isEditing"
|
||||
@ -48,7 +49,7 @@
|
||||
|
||||
<script>
|
||||
import ResizeHandle from './resizeHandle.vue';
|
||||
import SubobjectView from '../../displayLayout/components/SubobjectView.vue';
|
||||
import ObjectFrame from '../../../ui/components/ObjectFrame.vue';
|
||||
import isEditingMixin from '../mixins/isEditing';
|
||||
|
||||
export default {
|
||||
@ -57,26 +58,29 @@ export default {
|
||||
mixins: [isEditingMixin],
|
||||
data() {
|
||||
return {
|
||||
item: {domainObject: {}}
|
||||
domainObject: undefined,
|
||||
objectPath: undefined
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ResizeHandle,
|
||||
SubobjectView
|
||||
ObjectFrame
|
||||
},
|
||||
computed: {
|
||||
noFrame() {
|
||||
return this.frame.noFrame;
|
||||
hasFrame() {
|
||||
return !this.frame.noFrame;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setDomainObject(object) {
|
||||
this.item.domainObject = object;
|
||||
console.log('setting object!');
|
||||
this.domainObject = object;
|
||||
this.objectPath = [object];
|
||||
this.setSelection();
|
||||
},
|
||||
setSelection() {
|
||||
let context = {
|
||||
item: this.item.domainObject,
|
||||
item: this.domainObject,
|
||||
addContainer: this.addContainer,
|
||||
type: 'frame',
|
||||
frameId: this.frame.id
|
||||
|
@ -35,6 +35,9 @@ define([
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'flexible-layout';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'flexible-layout';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
|
@ -44,6 +44,7 @@ define([
|
||||
containers: [new Container.default(50), new Container.default(50)],
|
||||
rowsLayout: false
|
||||
};
|
||||
domainObject.composition = [];
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -30,7 +30,7 @@ define([
|
||||
function FolderGridView(openmct) {
|
||||
return {
|
||||
key: 'grid',
|
||||
name: 'Grid Vue',
|
||||
name: 'Grid View',
|
||||
cssClass: 'icon-thumbs-strip',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'folder';
|
||||
|
@ -32,7 +32,7 @@ define([
|
||||
function FolderListView(openmct) {
|
||||
return {
|
||||
key: 'list-view',
|
||||
name: 'List Vue',
|
||||
name: 'List View',
|
||||
cssClass: 'icon-list-view',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'folder';
|
||||
|
@ -149,8 +149,8 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import contextMenuGesture from '../../../ui/components/mixins/context-menu-gesture';
|
||||
import objectLink from '../../../ui/components/mixins/object-link';
|
||||
import contextMenuGesture from '../../../ui/mixins/context-menu-gesture';
|
||||
import objectLink from '../../../ui/mixins/object-link';
|
||||
|
||||
export default {
|
||||
mixins: [contextMenuGesture, objectLink],
|
||||
|
@ -4,9 +4,8 @@
|
||||
@click="navigate">
|
||||
<td class="c-list-item__name">
|
||||
<a :href="objectLink" ref="objectLink">
|
||||
<div class="c-list-item__type-icon"
|
||||
:class="item.type.cssClass"></div>
|
||||
{{item.model.name}}
|
||||
<div class="c-list-item__type-icon" :class="item.type.cssClass"></div>
|
||||
<div class="c-list-item__name-value">{{item.model.name}}</div>
|
||||
</a>
|
||||
</td>
|
||||
<td class="c-list-item__type">{{ item.type.name }}</td>
|
||||
@ -20,17 +19,24 @@
|
||||
|
||||
/******************************* LIST ITEM */
|
||||
.c-list-item {
|
||||
&__name {
|
||||
@include ellipsize();
|
||||
&__name a {
|
||||
display: flex;
|
||||
|
||||
> * + * { margin-left: $interiorMarginSm; }
|
||||
}
|
||||
|
||||
&__type-icon {
|
||||
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon
|
||||
color: $colorKey;
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
margin-right:$interiorMarginSm;
|
||||
}
|
||||
|
||||
&__name-value {
|
||||
@include ellipsize();
|
||||
}
|
||||
|
||||
&.is-alias {
|
||||
// Object is an alias to an original.
|
||||
[class*='__type-icon'] {
|
||||
@ -48,14 +54,13 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
import moment from 'moment';
|
||||
import contextMenuGesture from '../../../ui/components/mixins/context-menu-gesture';
|
||||
import objectLink from '../../../ui/components/mixins/object-link';
|
||||
import contextMenuGesture from '../../../ui/mixins/context-menu-gesture';
|
||||
import objectLink from '../../../ui/mixins/object-link';
|
||||
|
||||
export default {
|
||||
mixins: [contextMenuGesture, objectLink],
|
||||
|
@ -42,7 +42,8 @@
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<list-item v-for="(item,index) in sortedItems"
|
||||
<list-item v-for="item in sortedItems"
|
||||
:key="item.objectKeyString"
|
||||
:item="item"
|
||||
:object-path="item.objectPath">
|
||||
</list-item>
|
||||
@ -77,9 +78,12 @@
|
||||
|
||||
td {
|
||||
$p: floor($interiorMargin * 1.5);
|
||||
font-size: 1.1em;
|
||||
@include ellipsize();
|
||||
line-height: 120%; // Needed for icon alignment
|
||||
max-width: 0;
|
||||
padding-top: $p;
|
||||
padding-bottom: $p;
|
||||
width: 25%;
|
||||
|
||||
&:not(.c-list-item__name) {
|
||||
color: $colorItemFgDetails;
|
||||
@ -99,9 +103,20 @@ export default {
|
||||
mixins: [compositionLoader],
|
||||
inject: ['domainObject', 'openmct'],
|
||||
data() {
|
||||
let sortBy = 'model.name',
|
||||
ascending = true,
|
||||
persistedSortOrder = window.localStorage.getItem('openmct-listview-sort-order');
|
||||
|
||||
if (persistedSortOrder) {
|
||||
let parsed = JSON.parse(persistedSortOrder);
|
||||
|
||||
sortBy = parsed.sortBy;
|
||||
ascending = parsed.ascending;
|
||||
}
|
||||
|
||||
return {
|
||||
sortBy: 'model.name',
|
||||
ascending: true
|
||||
sortBy,
|
||||
ascending
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -121,6 +136,17 @@ export default {
|
||||
this.sortBy = field;
|
||||
this.ascending = defaultDirection;
|
||||
}
|
||||
|
||||
window.localStorage
|
||||
.setItem(
|
||||
'openmct-listview-sort-order',
|
||||
JSON.stringify(
|
||||
{
|
||||
sortBy: this.sortBy,
|
||||
ascending: this.ascending
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,8 @@ export default {
|
||||
model: child,
|
||||
type: type.definition,
|
||||
isAlias: this.domainObject.identifier.key !== child.location,
|
||||
objectPath: [child].concat(openmct.router.path)
|
||||
objectPath: [child].concat(this.openmct.router.path),
|
||||
objectKeyString: this.openmct.objects.makeKeyString(child.identifier)
|
||||
});
|
||||
},
|
||||
remove(identifier) {
|
||||
|
@ -21,27 +21,9 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/controllers/NotebookController",
|
||||
"./src/controllers/NewEntryController",
|
||||
"./src/controllers/SelectSnapshotController",
|
||||
"./src/actions/NewEntryContextual",
|
||||
"./src/actions/AnnotateSnapshot",
|
||||
"./src/directives/MCTSnapshot",
|
||||
"./res/templates/controls/snapSelect.html",
|
||||
"./res/templates/controls/embedControl.html",
|
||||
"./res/templates/annotation.html",
|
||||
"./res/templates/draggedEntry.html"
|
||||
"./src/controllers/NotebookController"
|
||||
], function (
|
||||
NotebookController,
|
||||
NewEntryController,
|
||||
SelectSnapshotController,
|
||||
newEntryAction,
|
||||
AnnotateSnapshotAction,
|
||||
MCTSnapshotDirective,
|
||||
snapSelectTemplate,
|
||||
embedControlTemplate,
|
||||
annotationTemplate,
|
||||
draggedEntryTemplate
|
||||
NotebookController
|
||||
) {
|
||||
var installed = false;
|
||||
|
||||
@ -87,90 +69,6 @@ define([
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
actions: [
|
||||
{
|
||||
"key": "notebook-new-entry",
|
||||
"implementation": newEntryAction,
|
||||
"name": "New Notebook Entry",
|
||||
"cssClass": "icon-notebook labeled",
|
||||
"description": "Add a new Notebook entry",
|
||||
"category": [
|
||||
"view-control"
|
||||
],
|
||||
"depends": [
|
||||
"$compile",
|
||||
"$rootScope",
|
||||
"dialogService",
|
||||
"notificationService",
|
||||
"linkService"
|
||||
],
|
||||
"priority": "preferred"
|
||||
},
|
||||
{
|
||||
"key": "annotate-snapshot",
|
||||
"implementation": AnnotateSnapshotAction,
|
||||
"name": "Annotate Snapshot",
|
||||
"cssClass": "icon-pencil labeled",
|
||||
"description": "Annotate embed's snapshot",
|
||||
"category": "embed",
|
||||
"depends": [
|
||||
"dialogService",
|
||||
"dndService",
|
||||
"$rootScope"
|
||||
]
|
||||
}
|
||||
],
|
||||
controllers: [
|
||||
{
|
||||
"key": "NewEntryController",
|
||||
"implementation": NewEntryController,
|
||||
"depends": ["$scope",
|
||||
"$rootScope"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "selectSnapshotController",
|
||||
"implementation": SelectSnapshotController,
|
||||
"depends": ["$scope",
|
||||
"$rootScope"
|
||||
]
|
||||
}
|
||||
],
|
||||
controls: [
|
||||
{
|
||||
"key": "snapshot-select",
|
||||
"template": snapSelectTemplate
|
||||
},
|
||||
{
|
||||
"key": "embed-control",
|
||||
"template": embedControlTemplate
|
||||
}
|
||||
],
|
||||
templates: [
|
||||
{
|
||||
"key": "annotate-snapshot",
|
||||
"template": annotationTemplate
|
||||
}
|
||||
],
|
||||
directives: [
|
||||
{
|
||||
"key": "mctSnapshot",
|
||||
"implementation": MCTSnapshotDirective,
|
||||
"depends": [
|
||||
"$rootScope",
|
||||
"$document",
|
||||
"exportImageService",
|
||||
"dialogService",
|
||||
"notificationService"
|
||||
]
|
||||
}
|
||||
],
|
||||
representations: [
|
||||
{
|
||||
"key": "draggedEntry",
|
||||
"template": draggedEntryTemplate
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
@ -1,2 +0,0 @@
|
||||
<div class="snap-annotation" id="snap-annotation" ng-controller="ngModel.controller">
|
||||
</div>
|
@ -1,51 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2009-2016, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!--
|
||||
This element appears in the overlay dialog when initiating a new Notebook Entry from a view's Notebook button -->
|
||||
<div class='form-control'>
|
||||
<ng-form name="mctControl">
|
||||
<div class='fields' ng-controller="NewEntryController">
|
||||
<div class="l-flex-row new-notebook-entry-embed l-entry-embed {{cssClass}}"
|
||||
ng-class="{ 'has-snapshot' : snapToggle }">
|
||||
<div class="holder flex-elem snap-thumb"
|
||||
ng-if="snapToggle">
|
||||
<img ng-src="{{snapshot.src}}" alt="{{snapshot.modified}}">
|
||||
</div>
|
||||
|
||||
<div class="holder flex-elem embed-info">
|
||||
<div class="embed-title">{{objectName}}</div>
|
||||
<div class="embed-date"
|
||||
ng-if="snapToggle">{{snapshot.modified| date:'yyyy-MM-dd HH:mm:ss'}}</div>
|
||||
</div>
|
||||
|
||||
<div class="holder flex-elem annotate-new"
|
||||
ng-if="snapToggle">
|
||||
<a class="s-button flex-elem icon-pencil "
|
||||
title="Annotate this snapshot"
|
||||
ng-click="annotateSnapshot()">
|
||||
<span class="title-label">Annotate</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ng-form>
|
||||
</div>
|
@ -1,38 +0,0 @@
|
||||
<!--
|
||||
Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
as represented by the Administrator of the National Aeronautics and Space
|
||||
Administration. All rights reserved.
|
||||
|
||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing permissions and limitations
|
||||
under the License.
|
||||
|
||||
Open MCT includes source code licensed under additional open source
|
||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
this source code distribution or the Licensing information page available
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="frame snap-frame frame-template t-frame-inner abs t-object-type-{{ representation.selected.key }}">
|
||||
<div class="abs object-browse-bar l-flex-row">
|
||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||
<mct-representation
|
||||
key="'switcher'"
|
||||
ng-model="representation"
|
||||
mct-object="domainObject">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
<div class="abs object-holder" data-entry = "{{parameters.entry}}" data-embed = "{{parameters.embed}}" mct-snapshot ng-if="representation.selected.key">
|
||||
<mct-representation
|
||||
key="representation.selected.key"
|
||||
mct-object="representation.selected.key && domainObject">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
@ -28,7 +28,7 @@
|
||||
</div>
|
||||
|
||||
<div class="c-ne__local-controls--hidden">
|
||||
<button class="c-click-icon icon-trash"
|
||||
<button class="c-click-icon c-click-icon--major icon-trash"
|
||||
title="Delete this entry"
|
||||
v-on:click="deleteEntry"></button>
|
||||
</div>
|
||||
|
@ -5,21 +5,17 @@
|
||||
@input="search"
|
||||
@clear="search">
|
||||
</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="newest" :selected="sortEntries === 'newest'">Newest first</option>
|
||||
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="c-notebook__controls ">
|
||||
<select class="c-notebook__controls__time" 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>
|
||||
<select class="c-notebook__controls__time" v-model="sortEntries">
|
||||
<option value="newest" :selected="sortEntries === 'newest'">Newest first</option>
|
||||
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-notebook__drag-area icon-plus"
|
||||
@ -31,8 +27,9 @@
|
||||
<div class="c-notebook__entries" ng-mouseover="handleActive()">
|
||||
<ul>
|
||||
<notebook-entry
|
||||
v-for="entry in filteredAndSortedEntries"
|
||||
v-bind:entry="entry">
|
||||
v-for="(entry,index) in filteredAndSortedEntries"
|
||||
:key="entry.key"
|
||||
:entry="entry">
|
||||
</notebook-entry>
|
||||
</ul>
|
||||
</div>
|
||||
|
@ -1,162 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining viewSnapshot (Originally NewWindowAction). Created by vwoeltje on 11/18/14.
|
||||
*/
|
||||
define(
|
||||
["painterro", "zepto"],
|
||||
function (Painterro, $) {
|
||||
|
||||
var annotationStruct = {
|
||||
title: "Annotate Snapshot",
|
||||
template: "annotate-snapshot",
|
||||
options: [{
|
||||
name: "OK",
|
||||
key: "ok",
|
||||
description: "save annotation"
|
||||
},
|
||||
{
|
||||
name: "Cancel",
|
||||
key: "cancel",
|
||||
description: "cancel editing"
|
||||
}]
|
||||
};
|
||||
|
||||
function AnnotateSnapshot(dialogService, dndService, $rootScope, context) {
|
||||
context = context || {};
|
||||
|
||||
// Choose the object to be opened into a new tab
|
||||
this.domainObject = context.selectedObject || context.domainObject;
|
||||
this.dialogService = dialogService;
|
||||
this.dndService = dndService;
|
||||
this.$rootScope = $rootScope;
|
||||
}
|
||||
|
||||
AnnotateSnapshot.prototype.perform = function ($event, snapshot, embedId, entryId) {
|
||||
|
||||
var DOMAIN_OBJECT = this.domainObject;
|
||||
var ROOTSCOPE = this.$rootScope;
|
||||
var painterro;
|
||||
var save = false;
|
||||
|
||||
var controller = ['$scope', '$timeout', function PainterroController($scope, $timeout) {
|
||||
$(document.body).find('.l-dialog .outer-holder').addClass('annotation-dialog');
|
||||
|
||||
// Timeout is necessary because Painterro uses document.getElementById, and mct-include
|
||||
// hasn't added the dialog to the DOM yet.
|
||||
$timeout(function () {
|
||||
painterro = Painterro({
|
||||
id: 'snap-annotation',
|
||||
activeColor: '#ff0000',
|
||||
activeColorAlpha: 1.0,
|
||||
activeFillColor: '#fff',
|
||||
activeFillColorAlpha: 0.0,
|
||||
backgroundFillColor: '#000',
|
||||
backgroundFillColorAlpha: 0.0,
|
||||
defaultFontSize: 16,
|
||||
defaultLineWidth: 2,
|
||||
defaultTool: 'ellipse',
|
||||
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
|
||||
translation: {
|
||||
name: 'en',
|
||||
strings: {
|
||||
lineColor: 'Line',
|
||||
fillColor: 'Fill',
|
||||
lineWidth: 'Size',
|
||||
textColor: 'Color',
|
||||
fontSize: 'Size',
|
||||
fontStyle: 'Style'
|
||||
}
|
||||
},
|
||||
saveHandler: function (image, done) {
|
||||
if (save) {
|
||||
if (entryId && embedId) {
|
||||
var elementPos = DOMAIN_OBJECT.model.entries.map(function (x) {
|
||||
return x.createdOn;
|
||||
}).indexOf(entryId);
|
||||
var entryEmbeds = DOMAIN_OBJECT.model.entries[elementPos].embeds;
|
||||
var embedPos = entryEmbeds.map(function (x) {
|
||||
return x.id;
|
||||
}).indexOf(embedId);
|
||||
|
||||
saveSnap(image.asBlob(), embedPos, elementPos, DOMAIN_OBJECT);
|
||||
}else {
|
||||
ROOTSCOPE.snapshot = {'src': image.asDataURL('image/png'),
|
||||
'modified': Date.now()};
|
||||
}
|
||||
}
|
||||
done(true);
|
||||
}
|
||||
}).show(snapshot);
|
||||
});
|
||||
}];
|
||||
|
||||
annotationStruct.model = {'controller': controller};
|
||||
|
||||
function saveNotes(param) {
|
||||
if (param === 'ok') {
|
||||
save = true;
|
||||
}else {
|
||||
save = false;
|
||||
ROOTSCOPE.snapshot = "annotationCancelled";
|
||||
}
|
||||
painterro.save();
|
||||
}
|
||||
|
||||
function rejectNotes() {
|
||||
save = false;
|
||||
ROOTSCOPE.snapshot = "annotationCancelled";
|
||||
painterro.save();
|
||||
}
|
||||
|
||||
function saveSnap(url, embedPos, entryPos, domainObject) {
|
||||
var snap = false;
|
||||
|
||||
if (embedPos !== -1 && entryPos !== -1) {
|
||||
var reader = new window.FileReader();
|
||||
reader.readAsDataURL(url);
|
||||
reader.onloadend = function () {
|
||||
snap = reader.result;
|
||||
domainObject.useCapability('mutation', function (model) {
|
||||
if (model.entries[entryPos]) {
|
||||
model.entries[entryPos].embeds[embedPos].snapshot = {
|
||||
'src': snap,
|
||||
'type': url.type,
|
||||
'size': url.size,
|
||||
'modified': Date.now()
|
||||
};
|
||||
model.entries[entryPos].embeds[embedPos].id = Date.now();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
this.dialogService.getUserChoice(annotationStruct)
|
||||
.then(saveNotes, rejectNotes);
|
||||
|
||||
};
|
||||
|
||||
return AnnotateSnapshot;
|
||||
}
|
||||
);
|
@ -1,204 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
var SNAPSHOT_TEMPLATE = '<mct-representation key="\'draggedEntry\'"' +
|
||||
'class="t-rep-frame holder"' +
|
||||
'mct-object="selObj">' +
|
||||
'</mct-representation>';
|
||||
|
||||
var NEW_TASK_FORM = {
|
||||
name: "Create a Notebook Entry",
|
||||
hint: "Please select one Notebook",
|
||||
sections: [{
|
||||
rows: [{
|
||||
name: 'Entry',
|
||||
key: 'entry',
|
||||
control: 'textarea',
|
||||
required: false,
|
||||
"cssClass": "l-textarea-sm"
|
||||
},
|
||||
{
|
||||
name: 'Embed Type',
|
||||
key: 'withSnapshot',
|
||||
control: 'snapshot-select',
|
||||
"options": [
|
||||
{
|
||||
"name": "Link and Snapshot",
|
||||
"value": true
|
||||
},
|
||||
{
|
||||
"name": "Link only",
|
||||
"value": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'Embed',
|
||||
key: 'embedObject',
|
||||
control: 'embed-control'
|
||||
},
|
||||
{
|
||||
name: 'Save in Notebook',
|
||||
key: 'saveNotebook',
|
||||
control: 'locator',
|
||||
validate: validateLocation
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
function NewEntryContextual($compile, $rootScope, dialogService, notificationService, linkService, context) {
|
||||
context = context || {};
|
||||
this.domainObject = context.selectedObject || context.domainObject;
|
||||
this.dialogService = dialogService;
|
||||
this.notificationService = notificationService;
|
||||
this.linkService = linkService;
|
||||
this.$rootScope = $rootScope;
|
||||
this.$compile = $compile;
|
||||
}
|
||||
|
||||
function validateLocation(newParentObj) {
|
||||
return newParentObj.model.type === 'notebook';
|
||||
}
|
||||
|
||||
|
||||
NewEntryContextual.prototype.perform = function () {
|
||||
var self = this;
|
||||
var domainObj = this.domainObject;
|
||||
var notification = this.notificationService;
|
||||
var dialogService = this.dialogService;
|
||||
var rootScope = this.$rootScope;
|
||||
rootScope.newEntryText = '';
|
||||
// // Create the overlay element and add it to the document's body
|
||||
this.$rootScope.selObj = domainObj;
|
||||
this.$rootScope.selValue = "";
|
||||
var newScope = rootScope.$new();
|
||||
newScope.selObj = domainObj;
|
||||
newScope.selValue = "";
|
||||
this.$compile(SNAPSHOT_TEMPLATE)(newScope);
|
||||
|
||||
this.$rootScope.$watch("snapshot", setSnapshot);
|
||||
|
||||
function setSnapshot(value) {
|
||||
if (value === "annotationCancelled") {
|
||||
rootScope.snapshot = rootScope.lastValue;
|
||||
rootScope.lastValue = '';
|
||||
|
||||
} else if (value && value !== rootScope.lastValue) {
|
||||
var overlayModel = {
|
||||
title: NEW_TASK_FORM.name,
|
||||
message: NEW_TASK_FORM.message,
|
||||
structure: NEW_TASK_FORM,
|
||||
value: {'entry': rootScope.newEntryText || ""}
|
||||
};
|
||||
|
||||
rootScope.currentDialog = overlayModel;
|
||||
|
||||
dialogService.getDialogResponse(
|
||||
"overlay-dialog",
|
||||
overlayModel,
|
||||
function () {
|
||||
return overlayModel.value;
|
||||
}
|
||||
).then(addNewEntry);
|
||||
|
||||
rootScope.lastValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
function addNewEntry(options) {
|
||||
options.selectedModel = options.embedObject.getModel();
|
||||
options.cssClass = options.embedObject.getCapability('type').typeDef.cssClass;
|
||||
if (self.$rootScope.snapshot) {
|
||||
options.snapshot = self.$rootScope.snapshot;
|
||||
self.$rootScope.snapshot = undefined;
|
||||
}else {
|
||||
options.snapshot = undefined;
|
||||
}
|
||||
|
||||
if (!options.withSnapshot) {
|
||||
options.snapshot = '';
|
||||
}
|
||||
|
||||
createSnap(options);
|
||||
}
|
||||
|
||||
function createSnap(options) {
|
||||
options.saveNotebook.useCapability('mutation', function (model) {
|
||||
var entries = model.entries;
|
||||
var lastEntry = entries[entries.length - 1];
|
||||
var date = Date.now();
|
||||
|
||||
if (lastEntry === undefined || lastEntry.text || lastEntry.embeds) {
|
||||
model.entries.push({
|
||||
'id': date,
|
||||
'createdOn': date,
|
||||
'text': options.entry,
|
||||
'embeds': [{'type': options.embedObject.getId(),
|
||||
'id': '' + date,
|
||||
'cssClass': options.cssClass,
|
||||
'name': options.selectedModel.name,
|
||||
'snapshot': options.snapshot
|
||||
}]
|
||||
});
|
||||
}else {
|
||||
model.entries[entries.length - 1] = {
|
||||
'id': date,
|
||||
'createdOn': date,
|
||||
'text': options.entry,
|
||||
'embeds': [{'type': options.embedObject.getId(),
|
||||
'id': '' + date,
|
||||
'cssClass': options.cssClass,
|
||||
'name': options.selectedModel.name,
|
||||
'snapshot': options.snapshot
|
||||
}]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
notification.info({
|
||||
title: "Notebook Entry created"
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
NewEntryContextual.appliesTo = function (context) {
|
||||
var domainObject = context.domainObject;
|
||||
|
||||
if (domainObject) {
|
||||
if (domainObject.getModel().type === 'notebook') {
|
||||
// do not allow in context of a notebook
|
||||
return false;
|
||||
} else if (domainObject.getModel().type.includes('imagery')) {
|
||||
// do not allow in the context of an object with imagery
|
||||
// (because of cross domain issue with snapshot)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
return NewEntryContextual;
|
||||
}
|
||||
);
|
@ -1,130 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
define(
|
||||
['zepto'],
|
||||
function ($) {
|
||||
|
||||
function SnapshotAction (exportImageService, dialogService, context) {
|
||||
this.exportImageService = exportImageService;
|
||||
this.dialogService = dialogService;
|
||||
this.domainObject = context.domainObject;
|
||||
}
|
||||
|
||||
SnapshotAction.prototype.perform = function () {
|
||||
var elementToSnapshot =
|
||||
$(document.body).find(".overlay .object-holder")[0] ||
|
||||
$(document.body).find("[key='representation.selected.key']")[0];
|
||||
|
||||
$(elementToSnapshot).addClass("s-status-taking-snapshot");
|
||||
|
||||
this.exportImageService.exportPNGtoSRC(elementToSnapshot).then(function (blob) {
|
||||
$(elementToSnapshot).removeClass("s-status-taking-snapshot");
|
||||
|
||||
if (blob) {
|
||||
var reader = new window.FileReader();
|
||||
reader.readAsDataURL(blob);
|
||||
reader.onloadend = function () {
|
||||
this.saveSnapshot(reader.result, blob.type, blob.size);
|
||||
}.bind(this);
|
||||
}
|
||||
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
SnapshotAction.prototype.saveSnapshot = function (imageURL, imageType, imageSize) {
|
||||
var taskForm = this.generateTaskForm(),
|
||||
domainObject = this.domainObject,
|
||||
domainObjectId = domainObject.getId(),
|
||||
cssClass = domainObject.getCapability('type').typeDef.cssClass,
|
||||
name = domainObject.model.name;
|
||||
|
||||
this.dialogService.getDialogResponse(
|
||||
'overlay-dialog',
|
||||
taskForm,
|
||||
function () {
|
||||
return taskForm.value;
|
||||
}
|
||||
).then(function (options) {
|
||||
var snapshotObject = {
|
||||
src: imageURL,
|
||||
type: imageType,
|
||||
size: imageSize
|
||||
};
|
||||
|
||||
options.notebook.useCapability('mutation', function (model) {
|
||||
var date = Date.now();
|
||||
|
||||
model.entries.push({
|
||||
id: 'entry-' + date,
|
||||
createdOn: date,
|
||||
text: options.entry,
|
||||
embeds: [{
|
||||
name: name,
|
||||
cssClass: cssClass,
|
||||
type: domainObjectId,
|
||||
id: 'embed-' + date,
|
||||
createdOn: date,
|
||||
snapshot: snapshotObject
|
||||
}]
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
SnapshotAction.prototype.generateTaskForm = function () {
|
||||
var taskForm = {
|
||||
name: "Create a Notebook Entry",
|
||||
hint: "Please select a Notebook",
|
||||
sections: [{
|
||||
rows: [{
|
||||
name: 'Entry',
|
||||
key: 'entry',
|
||||
control: 'textarea',
|
||||
required: false,
|
||||
"cssClass": "l-textarea-sm"
|
||||
},
|
||||
{
|
||||
name: 'Save in Notebook',
|
||||
key: 'notebook',
|
||||
control: 'locator',
|
||||
validate: validateLocation
|
||||
}]
|
||||
}]
|
||||
};
|
||||
|
||||
var overlayModel = {
|
||||
title: taskForm.name,
|
||||
message: 'AHAHAH',
|
||||
structure: taskForm,
|
||||
value: {'entry': ""}
|
||||
};
|
||||
|
||||
function validateLocation(newParentObj) {
|
||||
return newParentObj.model.type === 'notebook';
|
||||
}
|
||||
|
||||
return overlayModel;
|
||||
};
|
||||
|
||||
return SnapshotAction;
|
||||
}
|
||||
);
|
@ -275,7 +275,6 @@ function (
|
||||
|
||||
function menuClickHandler(e) {
|
||||
e.stopPropagation();
|
||||
window.setTimeout(dismiss, 300);
|
||||
}
|
||||
|
||||
// Dismiss any menu which was already showing
|
||||
|
@ -107,10 +107,10 @@ function (
|
||||
|
||||
EntryController.prototype.dropOnEntry = function (entryid, event) {
|
||||
|
||||
var data = event.dataTransfer.getData('domainObject');
|
||||
var data = event.dataTransfer.getData('openmct/domain-object-path');
|
||||
|
||||
if (data) {
|
||||
var selectedObject = JSON.parse(data),
|
||||
var selectedObject = JSON.parse(data)[0],
|
||||
selectedObjectId = selectedObject.identifier.key,
|
||||
cssClass = this.openmct.types.get(selectedObject.type),
|
||||
entryPos = this.entryPosById(entryid),
|
||||
|
@ -1,65 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining NewEntryController. */
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
function NewEntryController($scope,$rootScope) {
|
||||
|
||||
$scope.snapshot = undefined;
|
||||
$scope.snapToggle = true;
|
||||
$scope.entryText = '';
|
||||
var annotateAction = $rootScope.selObj.getCapability('action').getActions({key: 'annotate-snapshot'})[0];
|
||||
|
||||
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = $rootScope.selObj;
|
||||
$scope.objectName = $rootScope.selObj.getModel().name;
|
||||
$scope.cssClass = $rootScope.selObj.getCapability('type').typeDef.cssClass;
|
||||
|
||||
$scope.annotateSnapshot = function ($event) {
|
||||
if ($rootScope.currentDialog.value) {
|
||||
$rootScope.newEntryText = $scope.$parent.$parent.ngModel.entry;
|
||||
$rootScope.currentDialog.cancel();
|
||||
annotateAction.perform($event, $rootScope.snapshot.src);
|
||||
$rootScope.currentDialog = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
function updateSnapshot(img) {
|
||||
$scope.snapshot = img;
|
||||
}
|
||||
// Update set of actions whenever the action capability
|
||||
// changes or becomes available.
|
||||
$rootScope.$watch("snapshot", updateSnapshot);
|
||||
|
||||
$rootScope.$watch("selValue", toggleEmbed);
|
||||
|
||||
function toggleEmbed(value) {
|
||||
$scope.snapToggle = value;
|
||||
}
|
||||
}
|
||||
|
||||
return NewEntryController;
|
||||
}
|
||||
);
|
@ -27,7 +27,7 @@ define([
|
||||
'../../res/templates/notebook.html',
|
||||
'../../res/templates/entry.html',
|
||||
'../../res/templates/embed.html',
|
||||
'../../../../ui/components/controls/search.vue'
|
||||
'../../../../ui/components/search.vue'
|
||||
],
|
||||
function (
|
||||
Vue,
|
||||
@ -120,8 +120,8 @@ function (
|
||||
var date = Date.now(),
|
||||
embed;
|
||||
|
||||
if (event.dataTransfer && event.dataTransfer.getData('domainObject')) {
|
||||
var selectedObject = JSON.parse(event.dataTransfer.getData('domainObject')),
|
||||
if (event.dataTransfer && event.dataTransfer.getData('openmct/domain-object-path')) {
|
||||
var selectedObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0],
|
||||
selectedObjectId = selectedObject.identifier.key,
|
||||
cssClass = this.openmct.types.get(selectedObject.type);
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Module defining SelectSnapshotController. */
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
function SelectSnapshotController($scope,$rootScope) {
|
||||
|
||||
$scope.selectModel = true;
|
||||
|
||||
function selectprint(value) {
|
||||
$rootScope.selValue = value;
|
||||
$scope.$parent.$parent.ngModel[$scope.$parent.$parent.field] = value;
|
||||
}
|
||||
|
||||
$scope.$watch("selectModel", selectprint);
|
||||
|
||||
}
|
||||
|
||||
return SelectSnapshotController;
|
||||
}
|
||||
);
|
@ -1,86 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2016, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(['zepto'], function ($) {
|
||||
function MCTSnapshot($rootScope, $document, exportImageService, dialogService, notificationService) {
|
||||
var document = $document[0];
|
||||
|
||||
function link($scope, $element, $attrs) {
|
||||
var objectElement = $(document.body).find(".overlay .object-holder")[0] || $(document.body).find("[key='representation.selected.key']")[0],
|
||||
takeSnapshot,
|
||||
makeImg,
|
||||
saveImg;
|
||||
|
||||
$(objectElement).addClass("s-status-taking-snapshot");
|
||||
|
||||
saveImg = function (url, entryId, embedId) {
|
||||
$scope.$parent.$parent.$parent.saveSnap(url, embedId, entryId);
|
||||
};
|
||||
|
||||
makeImg = function (el) {
|
||||
var scope = $scope;
|
||||
|
||||
exportImageService.exportPNGtoSRC(el).then(function (img) {
|
||||
|
||||
$(objectElement).removeClass("s-status-taking-snapshot");
|
||||
|
||||
if (img) {
|
||||
if ($element[0].dataset.entry && $element[0].dataset.embed) {
|
||||
saveImg(img, +$element[0].dataset.entry, +$element[0].dataset.embed);
|
||||
} else {
|
||||
var reader = new window.FileReader();
|
||||
reader.readAsDataURL(img);
|
||||
reader.onloadend = function () {
|
||||
$($element[0]).attr("data-snapshot", reader.result);
|
||||
$rootScope.snapshot = {
|
||||
'src': reader.result,
|
||||
'type': img.type,
|
||||
'size': img.size,
|
||||
'modified': Date.now()
|
||||
};
|
||||
scope.$destroy();
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
takeSnapshot = function () {
|
||||
makeImg(objectElement);
|
||||
};
|
||||
|
||||
takeSnapshot();
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
$element.remove();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: link
|
||||
};
|
||||
}
|
||||
|
||||
return MCTSnapshot;
|
||||
|
||||
});
|
@ -20,13 +20,13 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div class="gl-plot plot-legend-{{legend.get('position')}} {{legend.get('expanded')? 'plot-legend-expanded' : 'plot-legend-collapsed'}}">
|
||||
<div class="gl-plot-legend flex-elem l-flex-row"
|
||||
<div class="gl-plot-legend"
|
||||
ng-class="{ 'hover-on-plot': !!highlights.length }"
|
||||
ng-show="legend.get('position') !== 'hidden'">
|
||||
<span class="view-control flex-elem"
|
||||
ng-class="{ expanded: legend.get('expanded') }"
|
||||
<div class="gl-plot-legend__view-control c-disclosure-triangle is-enabled"
|
||||
ng-class="{ 'c-disclosure-triangle--expanded': legend.get('expanded') }"
|
||||
ng-click="legend.set('expanded', !legend.get('expanded'));">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- COLLAPSED PLOT LEGEND -->
|
||||
<div class="plot-wrapper-collapsed-legend">
|
||||
@ -52,7 +52,7 @@
|
||||
</div>
|
||||
|
||||
<!-- EXPANDED PLOT LEGEND -->
|
||||
<div class="plot-wrapper-expanded-legend flex-elem grows">
|
||||
<div class="plot-wrapper-expanded-legend">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@ -133,7 +133,9 @@
|
||||
ng-style="{
|
||||
left: (tickWidth + 30) + 'px'
|
||||
}">
|
||||
<span class="t-object-alert t-alert-unsynced" title="This plot is not currently displaying the latest data. Reset Pan/zoom to return to view latest data."></span>
|
||||
<span class="t-object-alert t-alert-unsynced"
|
||||
title="This plot is not currently displaying the latest data.
|
||||
Reset Pan/zoom to return to view latest data."></span>
|
||||
<div class="gl-plot-display-area">
|
||||
<mct-ticks axis="xAxis">
|
||||
<div class="gl-plot-hash hash-v"
|
||||
|
@ -20,20 +20,20 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div ng-controller="PlotOptionsController">
|
||||
<ul class="tree">
|
||||
<ul class="tree c-tree">
|
||||
<h2 title="Plot series display properties in this object">Plot Series</h2>
|
||||
<li ng-repeat="series in config.series.models">
|
||||
<span class="tree-item menus-to-left">
|
||||
<span class='ui-symbol view-control flex-elem'
|
||||
ng-class="{ expanded: series.expanded }"
|
||||
<div class="c-tree__item menus-to-left">
|
||||
<span class='c-disclosure-triangle is-enabled flex-elem'
|
||||
ng-class="{ 'c-disclosure-triangle--expanded': series.expanded }"
|
||||
ng-click="series.expanded = !series.expanded">
|
||||
</span>
|
||||
<mct-representation
|
||||
class="rep-object-label"
|
||||
class="rep-object-label c-tree__item__label"
|
||||
key="'label'"
|
||||
mct-object="series.oldObject">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</div>
|
||||
<ul class="grid-properties" ng-show="series.expanded">
|
||||
<li class="grid-row">
|
||||
<div class="grid-cell label"
|
||||
@ -70,17 +70,9 @@
|
||||
<div class="grid-cell label"
|
||||
title="The plot line and marker color for this series.">Color</div>
|
||||
<div class="grid-cell value">
|
||||
<!-- TODO: get this into a class -->
|
||||
<span class="color-swatch"
|
||||
<span class="c-color-swatch"
|
||||
ng-style="{
|
||||
'background': series.get('color').asHexString(),
|
||||
'display': 'inline-block',
|
||||
'border': '1px solid rgba(255, 255, 255, 0.2)',
|
||||
'height': '10px',
|
||||
'width': '10px',
|
||||
'vertical-align': 'middle',
|
||||
'margin-left': '3px',
|
||||
'margin-top': -'2px'
|
||||
'background': series.get('color').asHexString()
|
||||
}">
|
||||
</span>
|
||||
</div>
|
||||
|
@ -20,49 +20,45 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<div ng-controller="PlotOptionsController">
|
||||
<ul class="tree l-inspector-part">
|
||||
<h2 title="Display properties for this object">Plot Series Options</h2>
|
||||
<ul class="tree c-tree">
|
||||
<h2 title="Display properties for this object">Plot Series</h2>
|
||||
<li ng-repeat="series in plotSeries"
|
||||
ng-controller="PlotSeriesFormController"
|
||||
form-model="series">
|
||||
<span class="tree-item menus-to-left">
|
||||
<span class='ui-symbol view-control flex-elem'
|
||||
ng-class="{ expanded: expanded }"
|
||||
<div class="c-tree__item menus-to-left">
|
||||
<span class='c-disclosure-triangle is-enabled flex-elem'
|
||||
ng-class="{ 'c-disclosure-triangle--expanded': expanded }"
|
||||
ng-click="expanded = !expanded">
|
||||
</span>
|
||||
<mct-representation class="rep-object-label"
|
||||
<mct-representation class="rep-object-label c-tree__item__label"
|
||||
key="'label'"
|
||||
mct-object="series.oldObject">
|
||||
</mct-representation>
|
||||
</span>
|
||||
</div>
|
||||
<ul class="grid-properties" ng-show="expanded">
|
||||
<li class="grid-row">
|
||||
<!-- Value to be displayed -->
|
||||
<div class="grid-cell label"
|
||||
title="The field to be plotted as a value for this series.">Value</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="select">
|
||||
<select ng-model="form.yKey">
|
||||
<option ng-repeat="option in yKeyOptions"
|
||||
value="{{option.value}}"
|
||||
ng-selected="option.value == form.yKey">
|
||||
{{option.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<select ng-model="form.yKey">
|
||||
<option ng-repeat="option in yKeyOptions"
|
||||
value="{{option.value}}"
|
||||
ng-selected="option.value == form.yKey">
|
||||
{{option.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid-row">
|
||||
<div class="grid-cell label"
|
||||
title="The line rendering style for this series.">Line Style</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="select">
|
||||
<select ng-model="form.interpolate">
|
||||
<option value="none">None</option>
|
||||
<option value="linear">Linear interpolate</option>
|
||||
<option value="stepAfter">Step after</option>
|
||||
</select>
|
||||
</div>
|
||||
<select ng-model="form.interpolate">
|
||||
<option value="none">None</option>
|
||||
<option value="linear">Linear interpolate</option>
|
||||
<option value="stepAfter">Step after</option>
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid-row">
|
||||
@ -78,7 +74,7 @@
|
||||
<li class="grid-row" ng-show="form.markers || form.alarmMarkers">
|
||||
<div class="grid-cell label"
|
||||
title="The size of regular and alarm markers for this series.">Marker Size:</div>
|
||||
<div class="grid-cell value"><input class="sm" type="text" ng-model="form.markerSize"/></div>
|
||||
<div class="grid-cell value"><input class="c-input--flex" type="text" ng-model="form.markerSize"/></div>
|
||||
</li>
|
||||
<li class="grid-row"
|
||||
ng-controller="ClickAwayController as toggle"
|
||||
@ -86,14 +82,14 @@
|
||||
<div class="grid-cell label"
|
||||
title="Manually set the plot line and marker color for this series.">Color</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="s-menu-button" ng-click="toggle.toggle()">
|
||||
<span class="color-swatch" ng-style="{ background: series.get('color').asHexString() }">
|
||||
<div class="c-click-swatch c-click-swatch--menu" ng-click="toggle.toggle()">
|
||||
<span class="c-color-swatch"
|
||||
ng-style="{ background: series.get('color').asHexString() }">
|
||||
</span>
|
||||
</div>
|
||||
<div class="l-inline-palette" ng-show="toggle.isActive()">
|
||||
<!-- TODO: redo this as a grid -->
|
||||
<div class="l-palette-row" ng-repeat="group in config.series.palette.groups()">
|
||||
<div class="l-palette-item s-palette-item"
|
||||
<div class="c-palette--inline c-palette__items" ng-show="toggle.isActive()">
|
||||
<div class="u-contents" ng-repeat="group in config.series.palette.groups()">
|
||||
<div class="c-palette__item"
|
||||
ng-repeat="color in group"
|
||||
ng-class="{ 'selected': series.get('color').equalTo(color) }"
|
||||
ng-style="{ background: color.asHexString() }"
|
||||
@ -115,7 +111,7 @@
|
||||
<li class="grid-row">
|
||||
<div class="grid-cell label"
|
||||
title="Manually override how the Y axis is labeled.">Label</div>
|
||||
<div class="grid-cell value"><input class="control" type="text" ng-model="form.label"/></div>
|
||||
<div class="grid-cell value"><input class="c-input--flex" type="text" ng-model="form.label"/></div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="l-inspector-part">
|
||||
@ -130,7 +126,7 @@
|
||||
title="Percentage of padding above and below plotted min and max values. 0.1, 1.0, etc.">
|
||||
Padding</div>
|
||||
<div class="grid-cell value">
|
||||
<input class="sm" type="text" ng-model="form.autoscalePadding"/>
|
||||
<input class="c-input--flex" type="text" ng-model="form.autoscalePadding"/>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@ -143,13 +139,13 @@
|
||||
<div class="grid-cell label"
|
||||
title="Minimum Y axis value.">Minimum Value</div>
|
||||
<div class="grid-cell value">
|
||||
<input class="sm" type="number" ng-model="form.range.min"/>
|
||||
<input class="c-input--flex" type="number" ng-model="form.range.min"/>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid-row">
|
||||
<div class="grid-cell label"
|
||||
title="Maximum Y axis value.">Maximum Value</div>
|
||||
<div class="grid-cell value"><input class="sm" type="number" ng-model="form.range.max"/></div>
|
||||
<div class="grid-cell value"><input class="c-input--flex" type="number" ng-model="form.range.max"/></div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -160,15 +156,13 @@
|
||||
<div class="grid-cell label"
|
||||
title="The position of the legend relative to the plot display area.">Position</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="select">
|
||||
<select ng-model="form.position">
|
||||
<option value="hidden">Hidden</option>
|
||||
<option value="top">Top</option>
|
||||
<option value="right">Right</option>
|
||||
<option value="bottom">Bottom</option>
|
||||
<option value="left">Left</option>
|
||||
</select>
|
||||
</div>
|
||||
<select ng-model="form.position">
|
||||
<option value="hidden">Hidden</option>
|
||||
<option value="top">Top</option>
|
||||
<option value="right">Right</option>
|
||||
<option value="bottom">Bottom</option>
|
||||
<option value="left">Left</option>
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid-row">
|
||||
@ -180,15 +174,13 @@
|
||||
<div class="grid-cell label"
|
||||
title="What to display in the legend when it's collapsed.">When collapsed show</div>
|
||||
<div class="grid-cell value">
|
||||
<div class="select">
|
||||
<select ng-model="form.valueToShowWhenCollapsed">
|
||||
<option value="none">nothing</option>
|
||||
<option value="nearestTimestamp">nearest timestamp</option>
|
||||
<option value="nearestValue">nearest Value</option>
|
||||
<option value="min">minimum value</option>
|
||||
<option value="max">maximum value</option>
|
||||
</select>
|
||||
</div>
|
||||
<select ng-model="form.valueToShowWhenCollapsed">
|
||||
<option value="none">Nothing</option>
|
||||
<option value="nearestTimestamp">Nearest timestamp</option>
|
||||
<option value="nearestValue">Nearest value</option>
|
||||
<option value="min">Minimum value</option>
|
||||
<option value="max">Maximum value</option>
|
||||
</select>
|
||||
</div>
|
||||
</li>
|
||||
<li class="grid-row">
|
||||
|
@ -137,8 +137,8 @@ define(
|
||||
* @returns {promise}
|
||||
*/
|
||||
|
||||
ExportImageService.prototype.exportPNGtoSRC = function (element) {
|
||||
return this.renderElement(element, "png");
|
||||
ExportImageService.prototype.exportPNGtoSRC = function (element, className) {
|
||||
return this.renderElement(element, "png", className);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,7 @@ define([
|
||||
'./flexibleLayout/plugin',
|
||||
'./tabs/plugin',
|
||||
'../../platform/features/fixed/plugin',
|
||||
'./preview/plugin'
|
||||
'./LADTable/plugin'
|
||||
], function (
|
||||
_,
|
||||
UTCTimeSystem,
|
||||
@ -61,7 +61,7 @@ define([
|
||||
FlexibleLayout,
|
||||
Tabs,
|
||||
FixedView,
|
||||
PreviewPlugin
|
||||
LADTable
|
||||
) {
|
||||
var bundleMap = {
|
||||
LocalStorage: 'platform/persistence/local',
|
||||
@ -176,7 +176,7 @@ define([
|
||||
plugins.Tabs = Tabs;
|
||||
plugins.FixedView = FixedView;
|
||||
plugins.FlexibleLayout = FlexibleLayout;
|
||||
plugins.Preview = PreviewPlugin.default;
|
||||
plugins.LADTable = LADTable;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
@ -20,6 +20,9 @@ define([
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'summary-widget';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'summary-widget';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
var statusService = openmct.$injector.get('statusService');
|
||||
var objectId = objectUtils.makeKeyString(domainObject.identifier);
|
||||
@ -32,7 +35,6 @@ define([
|
||||
return new SummaryWidgetView(domainObject, openmct);
|
||||
}
|
||||
},
|
||||
editable: true,
|
||||
priority: function (domainObject) {
|
||||
if (domainObject.type === 'summary-widget') {
|
||||
return Number.MAX_VALUE;
|
||||
|
@ -15,14 +15,14 @@
|
||||
v-for="(tab,index) in tabsList"
|
||||
:key="index"
|
||||
:class="[
|
||||
{'is-current': tab=== currentTab},
|
||||
{'is-current': tab=== currentTab},
|
||||
tab.type.definition.cssClass
|
||||
]"
|
||||
@click="showTab(tab)">
|
||||
<span class="c-button__label">{{tab.model.name}}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="c-tabs-view__object-holder"
|
||||
<div class="c-tabs-view__object-holder"
|
||||
v-for="(object, index) in tabsList"
|
||||
:key="index"
|
||||
:class="{'invisible': object !== currentTab}">
|
||||
@ -86,7 +86,7 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ObjectView from '../../../ui/components/layout/ObjectView.vue';
|
||||
import ObjectView from '../../../ui/components/ObjectView.vue';
|
||||
|
||||
var unknownObjectType = {
|
||||
definition: {
|
||||
@ -147,7 +147,7 @@ export default {
|
||||
this.setCurrentTab = true;
|
||||
},
|
||||
dragstart (e) {
|
||||
if (e.dataTransfer.getData('domainObject')) {
|
||||
if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||
this.isDragging = true;
|
||||
}
|
||||
},
|
||||
|
@ -35,6 +35,9 @@ define([
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'tabs';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'tabs';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
|
@ -79,8 +79,8 @@ define([
|
||||
|
||||
loadComposition() {
|
||||
this.tableComposition = this.openmct.composition.get(this.domainObject);
|
||||
if (this.tableComposition !== undefined){
|
||||
this.tableComposition.load().then((composition)=>{
|
||||
if (this.tableComposition !== undefined) {
|
||||
this.tableComposition.load().then((composition) => {
|
||||
composition = composition.filter(this.isTelemetryObject);
|
||||
|
||||
this.configuration.addColumnsForAllObjects(composition);
|
||||
@ -122,7 +122,6 @@ define([
|
||||
|
||||
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
||||
this.boundedRows.add(telemetryRows);
|
||||
console.log('Loaded %i rows', telemetryRows.length);
|
||||
this.decrementOutstandingRequests();
|
||||
});
|
||||
}
|
||||
@ -131,7 +130,7 @@ define([
|
||||
* @private
|
||||
*/
|
||||
incrementOutstandingRequests() {
|
||||
if (this.outstandingRequests === 0){
|
||||
if (this.outstandingRequests === 0) {
|
||||
this.emit('outstanding-requests', true);
|
||||
}
|
||||
this.outstandingRequests++;
|
||||
@ -143,7 +142,7 @@ define([
|
||||
decrementOutstandingRequests() {
|
||||
this.outstandingRequests--;
|
||||
|
||||
if (this.outstandingRequests === 0){
|
||||
if (this.outstandingRequests === 0) {
|
||||
this.emit('outstanding-requests', false);
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ define([
|
||||
objectMutated(object) {
|
||||
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
|
||||
this.domainObject = object;
|
||||
//Was it the configuration that changed?
|
||||
if (!_.eq(object.configuration, this.oldConfiguration)) {
|
||||
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
|
||||
this.oldConfiguration = JSON.parse(JSON.stringify(this.getConfiguration()));
|
||||
@ -91,16 +92,19 @@ define([
|
||||
let columnsToRemove = this.columns[objectKeyString];
|
||||
|
||||
delete this.columns[objectKeyString];
|
||||
|
||||
let configuration = this.domainObject.configuration;
|
||||
let configurationChanged = false;
|
||||
columnsToRemove.forEach((column) => {
|
||||
//There may be more than one column with the same key (eg. time system columns)
|
||||
if (!this.hasColumnWithKey(column.getKey())) {
|
||||
let configuration = this.domainObject.configuration;
|
||||
delete configuration.hiddenColumns[column.getKey()];
|
||||
// If there are no more columns with this key, delete any configuration, and trigger
|
||||
// a column refresh.
|
||||
this.openmct.objects.mutate(this.domainObject, 'configuration', configuration);
|
||||
configurationChanged = true;
|
||||
}
|
||||
});
|
||||
if (configurationChanged) {
|
||||
this.updateConfiguration(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
hasColumnWithKey(columnKey) {
|
||||
|
@ -36,13 +36,13 @@ define([
|
||||
key: 'table',
|
||||
name: 'Telemetry Table',
|
||||
cssClass: 'icon-tabular-realtime',
|
||||
editable: function(domainObject) {
|
||||
return domainObject.type === 'table';
|
||||
},
|
||||
canView: function (domainObject) {
|
||||
canView(domainObject) {
|
||||
return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
|
||||
},
|
||||
view: function (domainObject) {
|
||||
canEdit(domainObject) {
|
||||
return domainObject.type === 'table';
|
||||
},
|
||||
view(domainObject) {
|
||||
let csvExporter = new CSVExporter.default();
|
||||
let table = new TelemetryTable(domainObject, openmct);
|
||||
let component;
|
||||
@ -67,7 +67,7 @@ define([
|
||||
}
|
||||
}
|
||||
},
|
||||
priority: function () {
|
||||
priority() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -34,8 +34,8 @@
|
||||
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
|
||||
<table class="c-table__headers c-telemetry-table__headers">
|
||||
<thead>
|
||||
<tr>
|
||||
<table-column-header
|
||||
<tr class="c-telemetry-table__headers__name">
|
||||
<table-column-header
|
||||
v-for="(title, key, headerIndex) in headers"
|
||||
:key="key"
|
||||
:headerKey="key"
|
||||
@ -50,7 +50,7 @@
|
||||
:sortOptions="sortOptions"
|
||||
>{{title}}</table-column-header>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr class="c-telemetry-table__headers__filter">
|
||||
<table-column-header
|
||||
v-for="(title, key, headerIndex) in headers"
|
||||
:key="key"
|
||||
@ -106,7 +106,6 @@
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
@import "~styles/table";
|
||||
|
||||
.c-telemetry-table__drop-target {
|
||||
position: absolute;
|
||||
@ -119,6 +118,9 @@
|
||||
|
||||
.c-telemetry-table {
|
||||
// Table that displays telemetry in a scrolling body area
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: flex-start;
|
||||
overflow: hidden;
|
||||
|
||||
th, td {
|
||||
@ -128,6 +130,10 @@
|
||||
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
|
||||
}
|
||||
|
||||
td {
|
||||
color: $colorTelemFresh;
|
||||
}
|
||||
|
||||
/******************************* WRAPPERS */
|
||||
&__headers-w {
|
||||
// Wraps __headers table
|
||||
@ -208,6 +214,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* EDITING */
|
||||
.is-editing {
|
||||
.c-telemetry-table__headers__name {
|
||||
th[draggable],
|
||||
th[draggable] > * {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
th[draggable]:hover {
|
||||
$b: $editSelectableColor;
|
||||
background: $b;
|
||||
> * { background: $b; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* LEGACY */
|
||||
.s-status-taking-snapshot,
|
||||
.overlay.snapshot {
|
||||
@ -219,7 +241,7 @@
|
||||
|
||||
<script>
|
||||
import TelemetryTableRow from './table-row.vue';
|
||||
import search from '../../../ui/components/controls/search.vue';
|
||||
import search from '../../../ui/components/search.vue';
|
||||
import TableColumnHeader from './table-column-header.vue';
|
||||
import _ from 'lodash';
|
||||
|
||||
@ -462,7 +484,7 @@ export default {
|
||||
},
|
||||
updateConfiguration(configuration) {
|
||||
this.isAutosizeEnabled = configuration.autosize;
|
||||
|
||||
|
||||
this.updateHeaders();
|
||||
this.$nextTick().then(this.calculateColumnWidths);
|
||||
},
|
||||
@ -539,7 +561,7 @@ export default {
|
||||
this.filterChanged = _.debounce(this.filterChanged, 500);
|
||||
},
|
||||
mounted() {
|
||||
|
||||
|
||||
this.table.on('object-added', this.addObject);
|
||||
this.table.on('object-removed', this.removeObject);
|
||||
this.table.on('outstanding-requests', this.outstandingRequests);
|
||||
|
@ -55,7 +55,8 @@ $basicCr: 4px;
|
||||
|
||||
// Base colors
|
||||
$colorBodyBg: #393939;
|
||||
$colorBodyFg: #aaa;
|
||||
$colorBodyFg: #aaaaaa;
|
||||
$colorBodyFgEm: #fff;
|
||||
$colorGenBg: #222;
|
||||
$colorHeadBg: #262626;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
@ -64,7 +65,7 @@ $colorStatusBarFg: $colorBodyFg;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeyFg: #fff;
|
||||
$colorKeyHov: #00c0f6;
|
||||
$colorKeyHov: #26d8ff;
|
||||
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
||||
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
||||
$colorKeySelectedBg: $colorKey;
|
||||
@ -110,32 +111,37 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||
// Base Colors
|
||||
$dlSpread: 20%;
|
||||
$editColor: #00c7c3;
|
||||
$editColorAlt: #9971ff;
|
||||
$editColorBgBase: darken($editColor, $dlSpread);
|
||||
$editColorBg: rgba($editColorBgBase, 0.2);
|
||||
$editColorFg: lighten($editColor, $dlSpread);
|
||||
$editColorHov: lighten($editColor, 20%);
|
||||
|
||||
// Canvas
|
||||
$editCanvasColorBg: $editColorBg; //#002524;
|
||||
$editCanvasColorGrid: rgba($editColorBgBase, 0.4); //lighten($editCanvasColorBg, 3%);
|
||||
$editCanvasColorBg: $editColorBg;
|
||||
$editCanvasColorGrid: rgba($editColorBgBase, 0.4);
|
||||
|
||||
// Selectable
|
||||
$editSelectableColor: #006563;
|
||||
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
||||
$editSelectableColorHov: lighten($editSelectableColor, 10%);
|
||||
|
||||
// Selectable selected
|
||||
$editSelectableColorSelected: $editSelectableColorHov;
|
||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
|
||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
||||
$editSelectableBorderSelected: 1px solid $editColor;
|
||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
||||
$editBorderDrilledIn: 1px dashed #9971ff;
|
||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
||||
$colorGridLines: rgba($editColor, 0.2);
|
||||
|
||||
/************************************************** BROWSING */
|
||||
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
|
||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
|
||||
|
||||
// Icons
|
||||
$colorIconAlias: #4af6f3;
|
||||
@ -165,6 +171,8 @@ $colorDropHint: $colorKey;
|
||||
$colorDropHintBg: darken($colorDropHint, 10%);
|
||||
$colorDropHintBgHov: $colorDropHint;
|
||||
$colorDropHintFg: lighten($colorDropHint, 40%);
|
||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: lighten($colorBodyBg, 15%);
|
||||
@ -217,20 +225,40 @@ $overlayColorFg: $colorMenuFg;
|
||||
$overlayCr: $interiorMarginLg;
|
||||
$overlayBrightnessAdjust: brightness(1.3);
|
||||
|
||||
// Toolbar
|
||||
$toolBarEditColorBg: darken($editColorBgBase, 5%);
|
||||
$toolBarEditColorFg: lighten($editColorBgBase, 20%);
|
||||
$toolBarEditColorBtnFg: $toolBarEditColorFg;
|
||||
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
|
||||
$toolBarEditColorBtnFgHover: lighten($toolBarEditColorFg, 10%);
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorDisabled: #555555;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
$colorIndicatorOff: #777777;
|
||||
|
||||
// Limits and staleness colors//
|
||||
// Staleness
|
||||
$colorTelemFresh: lighten($colorBodyFg, 20%);
|
||||
$colorTelemStale: darken($colorBodyFg, 20%);
|
||||
$styleTelemStale: italic;
|
||||
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
|
||||
$colorLimitYellowIc: #ffaa00;
|
||||
$colorLimitRedBg: rgba(red, 0.3);
|
||||
$colorLimitRedIc: red;
|
||||
|
||||
// Limits
|
||||
$colorLimitYellowBg: #ac7300;
|
||||
$colorLimitYellowFg: #ffe64d;
|
||||
$colorLimitYellowIc: #ffb607;
|
||||
$colorLimitRedBg: #940000;
|
||||
$colorLimitRedFg: #ffa489;
|
||||
$colorLimitRedIc: #ff4222;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorCommand: #3693bd;
|
||||
$colorInfo: #2294a2;
|
||||
$colorOk: #33cc33;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: $colorMenuBg;
|
||||
@ -250,8 +278,10 @@ $colorTabBorder: lighten($colorBodyBg, 10%);
|
||||
$colorTabBodyBg: $colorBodyBg;
|
||||
$colorTabBodyFg: lighten($colorBodyFg, 20%);
|
||||
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
|
||||
$colorTabHeaderFg: lighten($colorBodyFg, 20%);
|
||||
$colorTabHeaderFg: $colorBodyFg;
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -261,7 +291,6 @@ $opacityPlotHash: 0.2;
|
||||
$stylePlotHash: dashed;
|
||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||
$colorPlotLabelFg: darken($colorPlotFg, 20%);
|
||||
$legendCollapsedNameMaxW: 50%;
|
||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||
|
||||
// Tree
|
||||
@ -277,8 +306,8 @@ $colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: darken($editColor, 20%);
|
||||
$colorItemTreeEditingFg: $editColorFg;
|
||||
$colorItemTreeEditingIcon: $editColorFg;
|
||||
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
|
||||
$colorItemTreeVCHover: $colorKey;
|
||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||
$shdwItemTreeIcon: none;
|
||||
|
||||
// Images
|
||||
@ -352,28 +381,6 @@ $createBtnTextTransform: uppercase;
|
||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||
}
|
||||
|
||||
/**************************************************** NOT USED, LEAVE FOR NOW */
|
||||
// Slider controls, not in use
|
||||
/*
|
||||
$sliderColorBase: $colorKey;
|
||||
$sliderColorRangeHolder: rgba(black, 0.07);
|
||||
$sliderColorRange: rgba($sliderColorBase, 0.2);
|
||||
$sliderColorRangeHov: rgba($sliderColorBase, 0.4);
|
||||
$sliderColorKnob: darken($sliderColorBase, 20%);
|
||||
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
|
||||
$sliderColorRangeValHovBg: $sliderColorRange;
|
||||
$sliderColorRangeValHovFg: $colorBodyFg;
|
||||
$sliderKnobW: 15px;
|
||||
$sliderKnobR: 2px;
|
||||
*/
|
||||
|
||||
// Content status
|
||||
/*
|
||||
$colorAlert: #ff3c00;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorCommand: #3693bd;
|
||||
$colorInfo: #2294a2;
|
||||
$colorOk: #33cc33;
|
||||
*/
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||
}
|
||||
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/************************************************** MAELSTROM2 THEME CONSTANTS */
|
||||
/************************************************** MAELSTROM THEME CONSTANTS */
|
||||
|
||||
// Fonts
|
||||
@import url('https://fonts.googleapis.com/css?family=Chakra+Petch:400,600,700|Michroma|Teko:400,700');
|
||||
@ -60,6 +60,7 @@ $basicCr: 4px;
|
||||
// Base colors
|
||||
$colorBodyBg: #393939;
|
||||
$colorBodyFg: #ccc;
|
||||
$colorBodyFgEm: #fff;
|
||||
$colorGenBg: #222;
|
||||
$colorHeadBg: #262626;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
@ -68,7 +69,7 @@ $colorStatusBarFg: $colorBodyFg;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeyFg: #fff;
|
||||
$colorKeyHov: #00c0f6;
|
||||
$colorKeyHov: #26d8ff;
|
||||
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
||||
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
||||
$colorKeySelectedBg: $colorKey;
|
||||
@ -114,31 +115,37 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||
// Base Colors
|
||||
$dlSpread: 20%;
|
||||
$editColor: #00c7c3;
|
||||
$editColorBg: darken($editColor, $dlSpread);
|
||||
$editColorAlt: #9971ff;
|
||||
$editColorBgBase: darken($editColor, $dlSpread);
|
||||
$editColorBg: rgba($editColorBgBase, 0.2);
|
||||
$editColorFg: lighten($editColor, $dlSpread);
|
||||
$editColorHov: lighten($editColor, 20%);
|
||||
|
||||
// Canvas
|
||||
$editCanvasColorBg: #002524;
|
||||
$editCanvasColorGrid: darken($editCanvasColorBg, 2%);
|
||||
$editCanvasColorBg: $editColorBg;
|
||||
$editCanvasColorGrid: rgba($editColorBgBase, 0.4);
|
||||
|
||||
// Selectable
|
||||
$editSelectableColor: #006563;
|
||||
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
||||
$editSelectableColorHov: lighten($editSelectableColor, 10%);
|
||||
|
||||
// Selectable selected
|
||||
$editSelectableColorSelected: $editSelectableColorHov;
|
||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
|
||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
||||
$editSelectableBorderSelected: 1px solid $editColor;
|
||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
||||
$editBorderDrilledIn: 1px dashed #9971ff;
|
||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
||||
$colorGridLines: rgba($editColor, 0.2);
|
||||
|
||||
/************************************************** BROWSING */
|
||||
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
|
||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.5);
|
||||
|
||||
// Icons
|
||||
$colorIconAlias: #4af6f3;
|
||||
@ -168,6 +175,8 @@ $colorDropHint: $colorKey;
|
||||
$colorDropHintBg: darken($colorDropHint, 10%);
|
||||
$colorDropHintBgHov: $colorDropHint;
|
||||
$colorDropHintFg: lighten($colorDropHint, 40%);
|
||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: lighten($colorBodyBg, 15%);
|
||||
@ -220,20 +229,40 @@ $overlayColorFg: $colorMenuFg;
|
||||
$overlayCr: $interiorMarginLg;
|
||||
$overlayBrightnessAdjust: brightness(1.3);
|
||||
|
||||
// Toolbar
|
||||
$toolBarEditColorBg: darken($editColorBgBase, 5%);
|
||||
$toolBarEditColorFg: lighten($editColorBgBase, 20%);
|
||||
$toolBarEditColorBtnFg: $toolBarEditColorFg;
|
||||
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
|
||||
$toolBarEditColorBtnFgHover: lighten($toolBarEditColorFg, 10%);
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorDisabled: #555555;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
$colorIndicatorOff: #777777;
|
||||
|
||||
// Limits and staleness colors//
|
||||
// Staleness
|
||||
$colorTelemFresh: lighten($colorBodyFg, 20%);
|
||||
$colorTelemStale: darken($colorBodyFg, 20%);
|
||||
$styleTelemStale: italic;
|
||||
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
|
||||
$colorLimitYellowIc: #ffaa00;
|
||||
$colorLimitRedBg: rgba(red, 0.3);
|
||||
$colorLimitRedIc: red;
|
||||
|
||||
// Limits
|
||||
$colorLimitYellowBg: #ac7300;
|
||||
$colorLimitYellowFg: #ffe64d;
|
||||
$colorLimitYellowIc: #ffb607;
|
||||
$colorLimitRedBg: #940000;
|
||||
$colorLimitRedFg: #ffa489;
|
||||
$colorLimitRedIc: #ff4222;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorCommand: #3693bd;
|
||||
$colorInfo: #2294a2;
|
||||
$colorOk: #33cc33;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: $colorMenuBg;
|
||||
@ -253,8 +282,10 @@ $colorTabBorder: lighten($colorBodyBg, 10%);
|
||||
$colorTabBodyBg: $colorBodyBg;
|
||||
$colorTabBodyFg: lighten($colorBodyFg, 20%);
|
||||
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
|
||||
$colorTabHeaderFg: lighten($colorBodyFg, 20%);
|
||||
$colorTabHeaderFg: $colorBodyFg;
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -264,7 +295,6 @@ $opacityPlotHash: 0.2;
|
||||
$stylePlotHash: dashed;
|
||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||
$colorPlotLabelFg: darken($colorPlotFg, 20%);
|
||||
$legendCollapsedNameMaxW: 50%;
|
||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||
|
||||
// Tree
|
||||
@ -280,8 +310,8 @@ $colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: darken($editColor, 20%);
|
||||
$colorItemTreeEditingFg: $editColorFg;
|
||||
$colorItemTreeEditingIcon: $editColorFg;
|
||||
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
|
||||
$colorItemTreeVCHover: $colorKey;
|
||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||
$shdwItemTreeIcon: none;
|
||||
|
||||
// Images
|
||||
@ -355,6 +385,10 @@ $createBtnTextTransform: uppercase;
|
||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||
}
|
||||
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||
}
|
||||
|
||||
/**************************************************** OVERRIDES */
|
||||
.c-frame {
|
||||
&:not(.no-frame) {
|
||||
@ -369,4 +403,4 @@ $createBtnTextTransform: uppercase;
|
||||
border-right: $bLR !important;;
|
||||
padding: 5px 10px 10px 10px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ $basicCr: 4px;
|
||||
// Base colors
|
||||
$colorBodyBg: #fcfcfc;
|
||||
$colorBodyFg: #666;
|
||||
$colorBodyFgEm: #333;
|
||||
$colorGenBg: #fff;
|
||||
$colorHeadBg: #eee;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
@ -109,33 +110,38 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||
/************************************************** EDITING */
|
||||
// Base Colors
|
||||
$dlSpread: 20%;
|
||||
$editColor: #00c7c3;
|
||||
$editColorBgBase: darken($editColor, $dlSpread);
|
||||
$editColorBg: darken($editColor, $dlSpread);
|
||||
$editColorFg: lighten($editColor, $dlSpread);
|
||||
$editColor: #6afdff;
|
||||
$editColorAlt: #9971ff;
|
||||
$editColorBgBase: lighten($editColor, 20%);
|
||||
$editColorBg: $editColor;
|
||||
$editColorFg: darken($editColor, $dlSpread);
|
||||
$editColorHov: lighten($editColor, 20%);
|
||||
|
||||
// Canvas
|
||||
$editCanvasColorBg: #e6ffff;
|
||||
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
|
||||
$editCanvasColorBg: lighten($editColorBgBase, 5%);
|
||||
$editCanvasColorGrid: $editColorBgBase;
|
||||
|
||||
// Selectable
|
||||
$editSelectableColor: #acdad6;
|
||||
$editSelectableColor: #00b3b1;
|
||||
$editSelectableColorFg: darken($editSelectableColor, 20%);
|
||||
$editSelectableColorHov: darken($editSelectableColor, 10%);
|
||||
$editSelectableColorHov: darken($editSelectableColor, 20%);
|
||||
|
||||
// Selectable selected
|
||||
$editSelectableColorSelected: $editColor; //$editSelectableColorHov;
|
||||
$editSelectableColorSelected: #c60; //$editSelectableColorHov;
|
||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
|
||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColor;
|
||||
$editSelectableBorderSelected: 1px solid $editColor;
|
||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
||||
$editSelectableBorderSelected: 1px solid $editSelectableColorSelected;
|
||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
||||
$editBorderDrilledIn: 1px dashed #9971ff;
|
||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
||||
$colorGridLines: rgba($editColor, 0.2);
|
||||
|
||||
/************************************************** BROWSING */
|
||||
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
|
||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.5);
|
||||
|
||||
// Icons
|
||||
$colorIconAlias: #4af6f3;
|
||||
@ -165,6 +171,8 @@ $colorDropHint: $colorKey;
|
||||
$colorDropHintBg: lighten($colorDropHint, 30%);
|
||||
$colorDropHintBgHov: lighten($colorDropHint, 40%);
|
||||
$colorDropHintFg: lighten($colorDropHint, 0);
|
||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: lighten($colorBodyBg, 10%);
|
||||
@ -217,20 +225,40 @@ $overlayColorFg: $colorMenuFg;
|
||||
$overlayCr: $interiorMarginLg;
|
||||
$overlayBrightnessAdjust: brightness(1);
|
||||
|
||||
// Toolbar
|
||||
$toolBarEditColorBg: darken($editColorBgBase, 5%);
|
||||
$toolBarEditColorFg: rgba(black, 0.7);
|
||||
$toolBarEditColorBtnFg: $toolBarEditColorFg;
|
||||
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
|
||||
$toolBarEditColorBtnFgHover: rgba(black, 0.9);
|
||||
|
||||
// Indicator colors
|
||||
$colorIndicatorAvailable: $colorKey;
|
||||
$colorIndicatorDisabled: #444;
|
||||
$colorIndicatorOn: $colorOk;
|
||||
$colorIndicatorOff: #666;
|
||||
|
||||
// Limits and staleness colors//
|
||||
// Staleness
|
||||
$colorTelemFresh: darken($colorBodyFg, 20%);
|
||||
$colorTelemStale: lighten($colorBodyFg, 20%);
|
||||
$styleTelemStale: italic;
|
||||
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
|
||||
$colorLimitYellowIc: #ffaa00;
|
||||
$colorLimitRedBg: rgba(red, 0.3);
|
||||
$colorLimitRedIc: red;
|
||||
|
||||
// Limits
|
||||
$colorLimitYellowBg: #ffe64d;
|
||||
$colorLimitYellowFg: #7f4f20;
|
||||
$colorLimitYellowIc: #e7a115;
|
||||
$colorLimitRedBg: #ff0000;
|
||||
$colorLimitRedFg: #fff;
|
||||
$colorLimitRedIc: #ffa99a;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorCommand: #3693bd;
|
||||
$colorInfo: #2294a2;
|
||||
$colorOk: #33cc33;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: $colorMenuBg;
|
||||
@ -252,6 +280,8 @@ $colorTabBodyFg: darken($colorBodyFg, 20%);
|
||||
$colorTabHeaderBg: darken($colorBodyBg, 10%);
|
||||
$colorTabHeaderFg: darken($colorBodyFg, 20%);
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: darken($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: darken($colorTabGroupHeaderBg, 40%);
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -261,7 +291,6 @@ $opacityPlotHash: 0.2;
|
||||
$stylePlotHash: dashed;
|
||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||
$colorPlotLabelFg: lighten($colorPlotFg, 20%);
|
||||
$legendCollapsedNameMaxW: 50%;
|
||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||
|
||||
// Tree
|
||||
@ -277,8 +306,8 @@ $colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: $editColor;
|
||||
$colorItemTreeEditingFg: $editColorFg;
|
||||
$colorItemTreeEditingIcon: $editColorFg;
|
||||
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
|
||||
$colorItemTreeVCHover: $colorKey;
|
||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||
$shdwItemTreeIcon: none;
|
||||
|
||||
// Images
|
||||
@ -351,29 +380,6 @@ $createBtnTextTransform: uppercase;
|
||||
background: $c;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************** NOT USED, LEAVE FOR NOW */
|
||||
// Slider controls, not in use
|
||||
/*
|
||||
$sliderColorBase: $colorKey;
|
||||
$sliderColorRangeHolder: rgba(black, 0.07);
|
||||
$sliderColorRange: rgba($sliderColorBase, 0.2);
|
||||
$sliderColorRangeHov: rgba($sliderColorBase, 0.4);
|
||||
$sliderColorKnob: lighten($sliderColorBase, 20%);
|
||||
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
|
||||
$sliderColorRangeValHovBg: $sliderColorRange;
|
||||
$sliderColorRangeValHovFg: $colorBodyFg;
|
||||
$sliderKnobW: 15px;
|
||||
$sliderKnobR: 2px;
|
||||
*/
|
||||
|
||||
// Content status
|
||||
/*
|
||||
$colorAlert: #ff3c00;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorCommand: #3693bd;
|
||||
$colorInfo: #2294a2;
|
||||
$colorOk: #33cc33;
|
||||
*/
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect($bg, $fg, lighten($bg, 20%), none);
|
||||
}
|
||||
|
@ -50,6 +50,15 @@ $gridItemMobile: 32px;
|
||||
$tabularHeaderH: 22px;
|
||||
$tabularTdPadLR: $itemPadLR;
|
||||
$tabularTdPadTB: 2px;
|
||||
/*************** Plots */
|
||||
$plotYBarW: 60px;
|
||||
$plotYLabelMinH: 20px;
|
||||
$plotYLabelW: 10px;
|
||||
$plotXBarH: 20px;
|
||||
$plotLegendH: 20px;
|
||||
$plotSwatchD: 8px;
|
||||
$plotDisplayArea: (0, 0, $plotXBarH, $plotYBarW); // 1: Top, 2: right, 3: bottom, 4: left
|
||||
$plotMinH: 95px;
|
||||
|
||||
/************************** MOBILE */
|
||||
$mobileMenuIconD: 24px; // Used
|
||||
|
@ -31,11 +31,13 @@ button {
|
||||
@include cButton();
|
||||
}
|
||||
|
||||
.c-button--menu {
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
opacity: 0.5;
|
||||
.c-button {
|
||||
&--menu {
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,23 +46,25 @@ button {
|
||||
}
|
||||
|
||||
/********* Icon Buttons */
|
||||
.c-click-icon {
|
||||
.c-click-icon,
|
||||
.c-click-swatch {
|
||||
@include cClickIcon();
|
||||
|
||||
.c-click-icon__label {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
|
||||
&--menu {
|
||||
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.6em;
|
||||
font-size: 0.7em;
|
||||
margin-left: floor($interiorMarginSm * 0.8);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-click-icon {
|
||||
.c-click-icon__label {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
|
||||
&--swatched {
|
||||
// Color control, show swatch element
|
||||
@ -101,9 +105,10 @@ button {
|
||||
}
|
||||
/********* 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.
|
||||
// Used in tree items, plot legends. Always placed BEFORE an element.
|
||||
.c-disclosure-triangle {
|
||||
$d: 12px;
|
||||
color: $colorDisclosureCtrl;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -111,15 +116,22 @@ button {
|
||||
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;
|
||||
&.is-enabled {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $colorDisclosureCtrlHov;
|
||||
}
|
||||
|
||||
&:before {
|
||||
$s: .65;
|
||||
content: $glyph-icon-arrow-right-equilateral;
|
||||
display: block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 1rem * $s;
|
||||
transform-origin: center;
|
||||
transition: transform 100ms ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&--expanded {
|
||||
@ -154,6 +166,11 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
|
||||
.c-input {
|
||||
&--flex {
|
||||
width: 100%;
|
||||
min-width: 20px;
|
||||
}
|
||||
|
||||
&--datetime {
|
||||
// Sized for values such as 2018-09-28 22:32:33.468Z
|
||||
width: 160px;
|
||||
@ -211,6 +228,17 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
}
|
||||
|
||||
// SELECTS
|
||||
select {
|
||||
@include appearanceNone();
|
||||
@include themedSelect();
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-position: right .4em top 90%, 0 0;
|
||||
border: none;
|
||||
border-radius: $controlCr;
|
||||
padding: 1px 20px 1px $interiorMargin;
|
||||
}
|
||||
|
||||
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
||||
.c-hyperlink {
|
||||
&--link {
|
||||
@ -252,6 +280,7 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
color: $colorMenuHovIc;
|
||||
}
|
||||
}
|
||||
|
||||
&:before {
|
||||
color: $colorMenuIc;
|
||||
font-size: 1em;
|
||||
@ -335,16 +364,16 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
&__items {
|
||||
flex: 1 1 auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(10, [col] auto );
|
||||
grid-template-columns: repeat(auto-fill, 12px);
|
||||
grid-gap: 1px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
$d: 16px;
|
||||
$d: 12px;
|
||||
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
width: 16px; height: 16px;
|
||||
min-width: $d; min-height: $d;
|
||||
transition: $transOut;
|
||||
|
||||
&:hover {
|
||||
@ -375,6 +404,12 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** SWATCHES */
|
||||
.c-color-swatch {
|
||||
border: 1px solid rgba(#fff, 0.2);
|
||||
box-shadow: rgba(#000, 0.2) 0 0 0 1px;
|
||||
}
|
||||
|
||||
/******************************************************** TOOLBAR */
|
||||
.c-ctrl-wrapper {
|
||||
@include cCtrlWrapper();
|
||||
@ -397,21 +432,31 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
|
||||
.c-toolbar {
|
||||
$p: $interiorMargin;
|
||||
border-top: 1px solid $colorInteriorBorder;
|
||||
background: $toolBarEditColorBg;
|
||||
border-radius: $basicCr;
|
||||
height: $p + 24px; // Need to standardize the height
|
||||
padding-top: $p;
|
||||
padding: $p;
|
||||
|
||||
&__separator {
|
||||
@include cToolbarSeparator();
|
||||
}
|
||||
|
||||
.c-click-icon,
|
||||
.c-labeled-input {
|
||||
color: $toolBarEditColorBtnFg;
|
||||
}
|
||||
|
||||
.c-click-icon {
|
||||
@include cControl();
|
||||
$pLR: $interiorMargin - 1;
|
||||
$pTB: 2px;
|
||||
color: $colorBodyFg;
|
||||
padding: $pTB $pLR;
|
||||
|
||||
&:hover {
|
||||
background: $toolBarEditColorBtnBgHover !important;
|
||||
color: $toolBarEditColorBtnFgHover !important;
|
||||
}
|
||||
|
||||
&--swatched {
|
||||
padding-bottom: floor($pTB / 2);
|
||||
width: 2em; // Standardize the width
|
||||
@ -441,6 +486,10 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.c-palette {
|
||||
min-width: 136px;
|
||||
}
|
||||
}
|
||||
|
||||
/********* Button Sets */
|
||||
@ -453,10 +502,6 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
> * {
|
||||
// Assume buttons are immediate descendants
|
||||
flex: 0 0 auto;
|
||||
|
||||
+ * {
|
||||
// margin-left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
+ .c-button-set {
|
||||
@ -497,6 +542,54 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
> * + * { margin-left: $interiorMargin; }
|
||||
}
|
||||
|
||||
|
||||
/******************************************************** SLIDERS AND RANGE */
|
||||
@mixin sliderKnobRound() {
|
||||
$h: 12px;
|
||||
@include themedButton();
|
||||
cursor: pointer;
|
||||
width: $h;
|
||||
height: $h;
|
||||
border-radius: 50% !important;
|
||||
transform: translateY(-42%);
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
// HTML5 range inputs
|
||||
@include appearanceNone(); /* Hides the slider so that custom slider can be made */
|
||||
background: transparent; /* Otherwise white in Chrome */
|
||||
&:focus {
|
||||
outline: none; /* Removes the blue border. */
|
||||
}
|
||||
|
||||
// Thumb
|
||||
&::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
@include sliderKnobRound();
|
||||
}
|
||||
&::-moz-range-thumb {
|
||||
border: none;
|
||||
@include sliderKnobRound();
|
||||
}
|
||||
&::-ms-thumb {
|
||||
border: none;
|
||||
@include sliderKnobRound();
|
||||
}
|
||||
|
||||
// Track
|
||||
&::-webkit-slider-runnable-track {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
@include sliderTrack();
|
||||
}
|
||||
|
||||
&::-moz-range-track {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
@include sliderTrack();
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************** DRAG AND DROP */
|
||||
.c-drop-hint {
|
||||
// Used in Tabs View, Flexible Grid Layouts
|
||||
@ -545,3 +638,27 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************** LEGACY */
|
||||
|
||||
.l-btn-set {
|
||||
// Fixes
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.h-local-controls {
|
||||
&-overlay-content {
|
||||
box-shadow: $colorBodyBg 0 0 0 2px;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: $interiorMargin; top: $interiorMargin;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&-trans {
|
||||
// Has a translucent background plate
|
||||
background: rgba($colorBodyBg, 0.8);
|
||||
border-radius: $controlCr;
|
||||
}
|
||||
}
|
||||
|
@ -141,17 +141,22 @@ li {
|
||||
// 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"] {
|
||||
[class*='local-controls--hidden'] {
|
||||
transition: opacity 500ms ease-in-out;
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Look down up to two levels and display hidden LC's on hover
|
||||
&:hover {
|
||||
> [class*='local-controls--hidden'],
|
||||
> * > [class*='local-controls--hidden'],
|
||||
> * > * > [class*='local-controls--hidden'] {
|
||||
transition: opacity 50ms ease-in-out;
|
||||
opacity: 1;
|
||||
pointer-events: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** ICON BACKGROUNDS */
|
||||
@ -174,30 +179,6 @@ body.desktop .has-local-controls {
|
||||
}
|
||||
}
|
||||
|
||||
//[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;
|
||||
// }
|
||||
//}
|
||||
//}
|
||||
|
||||
/******************************************************** SELECTION AND EDITING */
|
||||
// Provides supporting styles for Display Layouts and augmented legacy Fixed Position view
|
||||
|
||||
@ -217,7 +198,7 @@ body.desktop .has-local-controls {
|
||||
/*************************** SELECTION */
|
||||
.u-inspectable {
|
||||
&:hover {
|
||||
box-shadow: $browseShdwSelectableHov;
|
||||
box-shadow: $browseSelectableShdwHov;
|
||||
}
|
||||
}
|
||||
|
||||
@ -226,13 +207,14 @@ body.desktop .has-local-controls {
|
||||
*:not(.is-drilled-in).c-frame {
|
||||
border: $editSelectableBorder;
|
||||
|
||||
&:hover {
|
||||
border: $editSelectableBorderHov;
|
||||
&:not([s-selected]) {
|
||||
&:hover {
|
||||
border: $editSelectableBorderHov;
|
||||
}
|
||||
}
|
||||
|
||||
&[s-selected],
|
||||
&.is-selected {
|
||||
border: $editSelectableBorderSelected;
|
||||
&[s-selected] {
|
||||
box-shadow: $editSelectableShdwSelected;
|
||||
|
||||
> .c-frame-edit {
|
||||
display: block; // Show the editing rect and handles
|
||||
@ -244,7 +226,7 @@ body.desktop .has-local-controls {
|
||||
border: $editBorderDrilledIn;
|
||||
}
|
||||
|
||||
*[s-selected] {
|
||||
.is-moveable {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
@ -526,42 +508,3 @@ a.disabled {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************** TEMP LEGACY FIXES */
|
||||
.overlay {
|
||||
.outer-holder {
|
||||
background: $colorMenuBg;
|
||||
color: $colorMenuFg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.form .form-row {
|
||||
.label {
|
||||
color: $colorMenuFg !important;
|
||||
}
|
||||
.selector-list {
|
||||
@include reactive-input();
|
||||
background: $colorInputBg !important;
|
||||
color: $colorInputFg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-symbol.view-control {
|
||||
display: block;
|
||||
transform-origin: center center;
|
||||
|
||||
&:before { content: $glyph-icon-arrow-right-equilateral; }
|
||||
|
||||
&.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.t-imagery {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.t-frame-outer {
|
||||
min-width: 200px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
614
src/styles-new/_legacy.scss
Normal file
614
src/styles-new/_legacy.scss
Normal file
@ -0,0 +1,614 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/********************************************************************* PLOTS */
|
||||
mct-plot {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
/********************************************* STACKED PLOT LAYOUT */
|
||||
.t-plot-stacked {
|
||||
.l-view-section {
|
||||
// Make this a flex container
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
.gl-plot.child-frame {
|
||||
mct-plot {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
flex: 1 1 auto;
|
||||
&:not(:first-child) {
|
||||
margin-top: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.s-status-timeconductor-unsynced .holder-plot {
|
||||
.t-object-alert.t-alert-unsynced {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot {
|
||||
color: $colorPlotFg;
|
||||
display: flex;
|
||||
font-size: 0.7rem;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
min-height: $plotMinH;
|
||||
|
||||
/********************************************* AXIS AND DISPLAY AREA */
|
||||
.plot-wrapper-axis-and-display-area {
|
||||
margin-top: $interiorMargin; // Keep the top tick label from getting clipped
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
.t-object-alert {
|
||||
position: absolute;
|
||||
display: block;
|
||||
font-size: 1.5em;
|
||||
top: $interiorMarginSm;
|
||||
left: $interiorMarginSm;
|
||||
z-index: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-wrapper-display-area-and-x-axis {
|
||||
// Holds the plot area and the X-axis only
|
||||
position: absolute;
|
||||
top: nth($plotDisplayArea, 1);
|
||||
right:0; //nth($plotDisplayArea, 2);
|
||||
bottom: 0;
|
||||
left: nth($plotDisplayArea, 4);
|
||||
|
||||
.gl-plot-display-area {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: nth($plotDisplayArea, 3);
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.gl-plot-axis-area.gl-plot-x {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: $plotXBarH;
|
||||
width: auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-axis-area {
|
||||
position: absolute;
|
||||
&.gl-plot-y {
|
||||
top: nth($plotDisplayArea, 1);
|
||||
right: auto;
|
||||
bottom: nth($plotDisplayArea, 3);
|
||||
left: 0;
|
||||
width: $plotYBarW;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-coords {
|
||||
box-sizing: border-box;
|
||||
border-radius: $controlCr;
|
||||
background: black;
|
||||
color: lighten($colorBodyFg, 30%);
|
||||
padding: 2px 5px;
|
||||
position: absolute;
|
||||
top: nth($plotDisplayArea,1) + $interiorMarginLg;
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: nth($plotDisplayArea,4) + $interiorMarginLg;
|
||||
z-index: 10;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-label,
|
||||
.l-plot-label {
|
||||
color: $colorPlotLabelFg;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
|
||||
&.gl-plot-x-label,
|
||||
&.l-plot-x-label {
|
||||
top: auto;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.gl-plot-y-label,
|
||||
&.l-plot-y-label {
|
||||
$x: -50%;
|
||||
$r: -90deg;
|
||||
transform-origin: 50% 0;
|
||||
transform: translateX($x) rotate($r);
|
||||
display: inline-block;
|
||||
margin-left: $interiorMargin; // Kick off the left edge
|
||||
left: 0;
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-x-options,
|
||||
.gl-plot-y-options {
|
||||
$h: 24px;
|
||||
position: absolute;
|
||||
height: $h;
|
||||
min-height: $h;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.gl-plot-x-options {
|
||||
transform: translateX(-50%);
|
||||
bottom: 0;
|
||||
left: 50%;
|
||||
}
|
||||
|
||||
.gl-plot-y-options {
|
||||
transform: translateY(-50%);
|
||||
min-width: 150px; // Need this due to enclosure of .select
|
||||
top: 50%;
|
||||
left: $plotYLabelW + $interiorMargin * 2;
|
||||
}
|
||||
|
||||
.t-plot-display-controls {
|
||||
position: absolute;
|
||||
top: $interiorMargin;
|
||||
right: $interiorMargin;
|
||||
}
|
||||
|
||||
.gl-plot-hash {
|
||||
position: absolute;
|
||||
opacity: $opacityPlotHash;
|
||||
&.hash-v {
|
||||
border-right: 1px $colorPlotHash $stylePlotHash;
|
||||
height: 100%;
|
||||
}
|
||||
&.hash-h {
|
||||
border-bottom: 1px $colorPlotHash $stylePlotHash;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-display-area,
|
||||
.plot-display-area {
|
||||
@if $colorPlotBg != none {
|
||||
background-color: $colorPlotBg;
|
||||
}
|
||||
cursor: crosshair;
|
||||
border: 1px solid $colorPlotAreaBorder;
|
||||
}
|
||||
|
||||
.tick {
|
||||
position: absolute;
|
||||
border: 0 $colorPlotHash solid;
|
||||
&.tick-x {
|
||||
border-right-width: 1px;
|
||||
height: 100%; // Assumption is that the tick will be in a holder that will set it's height;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-tick,
|
||||
.tick-label {
|
||||
@include reverseEllipsis();
|
||||
font-size: 0.7rem;
|
||||
position: absolute;
|
||||
&.gl-plot-x-tick-label,
|
||||
&.tick-label-x {
|
||||
right: auto;
|
||||
bottom: auto;
|
||||
left: auto;
|
||||
height: auto;
|
||||
width: 20%;
|
||||
margin-left: -10%;
|
||||
text-align: center;
|
||||
}
|
||||
&.gl-plot-y-tick-label,
|
||||
&.tick-label-y {
|
||||
top: auto;
|
||||
height: 1em;
|
||||
width: auto;
|
||||
margin-bottom: -0.5em;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-tick {
|
||||
&.gl-plot-x-tick-label {
|
||||
top: $interiorMargin;
|
||||
}
|
||||
&.gl-plot-y-tick-label {
|
||||
right: $interiorMargin;
|
||||
left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.tick-label {
|
||||
&.tick-label-x {
|
||||
top: 0;
|
||||
}
|
||||
&.tick-label-y {
|
||||
right: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.export-plot {
|
||||
$bg: white;
|
||||
$fg: black;
|
||||
$gry: #999;
|
||||
|
||||
background: $bg !important;
|
||||
z-index: -10;
|
||||
|
||||
.l-view-section {
|
||||
$m: $interiorMargin;
|
||||
top: $m !important;
|
||||
right: $m;
|
||||
bottom: $m;
|
||||
left: $m;
|
||||
|
||||
.s-status-timeconductor-unsynced .holder-plot {
|
||||
.t-object-alert.t-alert-unsynced {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot-display-area {
|
||||
background: none !important;
|
||||
border-color: $gry !important;
|
||||
|
||||
.gl-plot-local-controls,
|
||||
.h-local-controls {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.gl-plot {
|
||||
color: $fg;
|
||||
|
||||
.gl-plot-hash {
|
||||
opacity: 0.1;
|
||||
border-color: $fg;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
thead {
|
||||
border-bottom: none;
|
||||
|
||||
th {
|
||||
background: #eee;
|
||||
border-left-color: $bg;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
tr {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
tr {
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
td {
|
||||
color: $fg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************************** _LEGEND.SCSS */
|
||||
.gl-plot-legend {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
|
||||
&__view-control {
|
||||
padding-top: 2px;
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
|
||||
table {
|
||||
table-layout: fixed;
|
||||
th,
|
||||
td {
|
||||
@include ellipsize(); // Note: this won't work if table-layout uses anything other than fixed.
|
||||
padding: 1px 3px; // Tighter than standard tabular padding
|
||||
//width: 1%;
|
||||
}
|
||||
}
|
||||
|
||||
&.hover-on-plot {
|
||||
// User is hovering over the plot to get a value at a point
|
||||
.hover-value-enabled {
|
||||
background-color: $legendHoverValueBg;
|
||||
border-radius: $smallCr;
|
||||
padding: 0 $interiorMarginSm;
|
||||
|
||||
&.value-to-display-min:before {
|
||||
content: 'MIN ';
|
||||
}
|
||||
&.value-to-display-max:before {
|
||||
content: 'MAX ';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************** GENERAL STYLES, ALL STATES */
|
||||
.plot-legend-item {
|
||||
// General styles for legend items, both expanded and collapsed legend states
|
||||
.plot-series-color-swatch {
|
||||
border-radius: $smallCr;
|
||||
border: 1px solid $colorBodyBg;
|
||||
display: inline-block;
|
||||
height: $plotSwatchD;
|
||||
width: $plotSwatchD;
|
||||
}
|
||||
.plot-series-name {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.plot-series-value {
|
||||
@include ellipsize();
|
||||
}
|
||||
}
|
||||
|
||||
.plot-wrapper-expanded-legend {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.gl-plot {
|
||||
&.plot-legend-collapsed .plot-wrapper-expanded-legend { display: none; }
|
||||
&.plot-legend-expanded .plot-wrapper-collapsed-legend { display: none; }
|
||||
|
||||
/***************** GENERAL STYLES, COLLAPSED */
|
||||
&.plot-legend-collapsed {
|
||||
// .plot-legend-item is a span of spans.
|
||||
&.plot-legend-top .gl-plot-legend { margin-bottom: $interiorMargin; }
|
||||
&.plot-legend-bottom .gl-plot-legend { margin-top: $interiorMargin; }
|
||||
&.plot-legend-right .gl-plot-legend { margin-left: $interiorMargin; }
|
||||
&.plot-legend-left .gl-plot-legend { margin-right: $interiorMargin; }
|
||||
|
||||
.plot-legend-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: stretch;
|
||||
&:not(:first-child) {
|
||||
margin-left: $interiorMarginLg;
|
||||
}
|
||||
.plot-series-swatch-and-name,
|
||||
.plot-series-value {
|
||||
@include ellipsize();
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.plot-series-swatch-and-name {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
|
||||
.plot-series-value {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************** GENERAL STYLES, EXPANDED */
|
||||
&.plot-legend-expanded {
|
||||
.gl-plot-legend {
|
||||
max-height: 70%;
|
||||
}
|
||||
|
||||
.plot-wrapper-expanded-legend {
|
||||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/***************** TOP OR BOTTOM */
|
||||
&.plot-legend-top,
|
||||
&.plot-legend-bottom {
|
||||
// General styles when legend is on the top or bottom
|
||||
flex-direction: column;
|
||||
|
||||
&.plot-legend-collapsed {
|
||||
// COLLAPSED ON TOP OR BOTTOM
|
||||
.plot-wrapper-collapsed-legend {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************** EITHER SIDE */
|
||||
&.plot-legend-left,
|
||||
&.plot-legend-right {
|
||||
// If the legend is expanded, use flex-col instead so that the legend gets the width it needs.
|
||||
&.plot-legend-expanded {
|
||||
// EXPANDED, ON EITHER SIDE
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&.plot-legend-collapsed {
|
||||
// COLLAPSED, ON EITHER SIDE
|
||||
.gl-plot-legend {
|
||||
max-height: inherit;
|
||||
width: 25%;
|
||||
}
|
||||
.plot-wrapper-collapsed-legend {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
min-width: 0;
|
||||
flex: 1 1 auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.plot-legend-item {
|
||||
margin-bottom: 1px;
|
||||
margin-left: 0;
|
||||
flex-wrap: wrap;
|
||||
.plot-series-swatch-and-name {
|
||||
flex: 0 1 auto;
|
||||
min-width: 20%;
|
||||
}
|
||||
.plot-series-value {
|
||||
flex: 0 1 auto;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************** ON BOTTOM OR RIGHT */
|
||||
&.plot-legend-right:not(.plot-legend-expanded),
|
||||
&.plot-legend-bottom {
|
||||
.gl-plot-legend {
|
||||
order: 2;
|
||||
}
|
||||
.plot-wrapper-axis-and-display-area {
|
||||
order: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
/********************************************************* CLOCKS AND TIMERS */
|
||||
.c-clock,
|
||||
.c-timer {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.25em;
|
||||
|
||||
> * {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&__value {
|
||||
color: $colorBodyFgEm;
|
||||
}
|
||||
}
|
||||
|
||||
.c-clock {
|
||||
> * + * { margin-left: $interiorMargin; }
|
||||
}
|
||||
|
||||
.c-timer {
|
||||
$ctrlW: 22px;
|
||||
|
||||
&__controls {
|
||||
margin-right: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
transition: $transOut;
|
||||
width: 0;
|
||||
|
||||
.c-click-icon:before { font-size: 1em; }
|
||||
}
|
||||
|
||||
&__direction {
|
||||
font-size: 0.9em;
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
|
||||
&__ng-controller {
|
||||
font-size: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.c-timer__controls {
|
||||
transition: $transOut; // On purpose: want this to take a bit longer
|
||||
margin-right: $interiorMargin;
|
||||
width: $ctrlW * 2;
|
||||
}
|
||||
|
||||
&.is-stopped .c-timer__controls { width: $ctrlW; }
|
||||
}
|
||||
|
||||
&__direction,
|
||||
&__value {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&.is-started {
|
||||
.c-timer {
|
||||
&__direction,
|
||||
&__value {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************* VARIOUS */
|
||||
.overlay {
|
||||
.outer-holder {
|
||||
background: $colorMenuBg;
|
||||
color: $colorMenuFg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.form .form-row {
|
||||
.label {
|
||||
color: $colorMenuFg !important;
|
||||
}
|
||||
.selector-list {
|
||||
@include reactive-input();
|
||||
background: $colorInputBg !important;
|
||||
color: $colorInputFg !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ui-symbol.view-control {
|
||||
display: block;
|
||||
transform-origin: center center;
|
||||
|
||||
&:before { content: $glyph-icon-arrow-right-equilateral; }
|
||||
|
||||
&.expanded {
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
|
||||
.t-imagery {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.t-frame-outer {
|
||||
min-width: 200px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
@ -60,6 +60,16 @@
|
||||
width: $d;
|
||||
}
|
||||
|
||||
@mixin appearanceNone() {
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin isAlias() {
|
||||
&:after {
|
||||
color:$colorIconAlias;
|
||||
@ -133,6 +143,12 @@
|
||||
background-repeat: $repeatDir;
|
||||
}
|
||||
|
||||
@mixin sliderTrack($bg: $scrollbarTrackColorBg) {
|
||||
border-radius: 2px;
|
||||
box-sizing: border-box;
|
||||
background-color: $bg;
|
||||
}
|
||||
|
||||
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
|
||||
background-image: linear-gradient(-90deg,
|
||||
rgba($c, $a) 0%, rgba($c, $a) 50%,
|
||||
@ -188,7 +204,7 @@
|
||||
}
|
||||
|
||||
@mixin htmlInputReset() {
|
||||
appearance: none;
|
||||
@include appearanceNone();
|
||||
background: transparent;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
@ -257,6 +273,7 @@
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
line-height: $fs; // Remove effect on top and bottom padding
|
||||
overflow: hidden;
|
||||
|
||||
&:before,
|
||||
@ -266,6 +283,10 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&:before {
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
&:after {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
@ -273,22 +294,25 @@
|
||||
[class*="__label"] {
|
||||
@include ellipsize();
|
||||
display: block;
|
||||
line-height: $fs; // Remove effect on top and bottom padding
|
||||
font-size: $fs;
|
||||
}
|
||||
|
||||
&[class*='icon'] > [class*="__label"] {
|
||||
// When button holds both an icon and a label, provide margin between them.
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cButton() {
|
||||
@include cControl();
|
||||
@include themedButton();
|
||||
//@include buttonBehavior();
|
||||
border-radius: $controlCr;
|
||||
color: $colorBtnFg;
|
||||
cursor: pointer;
|
||||
padding: $interiorMargin floor($interiorMargin * 1.25);
|
||||
|
||||
&:after,
|
||||
> * {
|
||||
> * + * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
@ -323,13 +347,12 @@
|
||||
// Make the icon bigger relative to its container
|
||||
@include cControl();
|
||||
$pLR: 4px;
|
||||
$pTB: 3px;
|
||||
$pTB: 4px;
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
border-radius: $controlCr;
|
||||
color: $colorKey;
|
||||
cursor: pointer;
|
||||
padding: $pTB $pLR ;
|
||||
padding: $pTB $pLR;
|
||||
|
||||
@include hover() {
|
||||
background: $colorClickIconBgHov;
|
||||
@ -342,6 +365,10 @@
|
||||
// Needed for c-togglebutton.
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
&[class*="--major"] {
|
||||
color: $colorKey;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cCtrlWrapper {
|
||||
@ -412,6 +439,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cSelect($bg, $fg, $arwClr, $shdw) {
|
||||
$svgArwClr: str-slice(inspect($arwClr), 2, str-length(inspect($arwClr))); // Remove initial # in color value
|
||||
background: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10'%3e%3cpath fill='%23#{$svgArwClr}' d='M5 5l5-5H0z'/%3e%3c/svg%3e"), $bg;
|
||||
color: $fg;
|
||||
box-shadow: $shdw;
|
||||
}
|
||||
|
||||
@mixin wrappedInput() {
|
||||
// An input that is wrapped. Optionally includes a __label or icon element.
|
||||
// Based on .c-search.
|
||||
@ -500,5 +534,7 @@
|
||||
}
|
||||
|
||||
@mixin test($c: deeppink, $a: 0.3) {
|
||||
background: rgba($c, $a) !important;
|
||||
background-color: rgba($c, $a) !important;
|
||||
box-shadow: deeppink 0 0 10px 1px !important;
|
||||
}
|
||||
|
113
src/styles-new/_status.scss
Normal file
113
src/styles-new/_status.scss
Normal file
@ -0,0 +1,113 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
/*************************************************** MIXINS */
|
||||
@mixin statusStyle($bg, $fg, $ic) {
|
||||
background: $bg !important;
|
||||
background-color: $bg !important;
|
||||
color: $fg !important;
|
||||
&:before {
|
||||
color: $ic;
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.7em;
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin elementStatusColors($c) {
|
||||
// Sets bg and icon colors for elements
|
||||
background: rgba($c, 0.5) !important;
|
||||
&:before {
|
||||
color: $c !important;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin indicatorStatusColors($c) {
|
||||
&:before, .count {
|
||||
color: $c;
|
||||
}
|
||||
}
|
||||
|
||||
.is-limit--yellow {
|
||||
@include statusStyle($colorLimitYellowBg, $colorLimitYellowFg, $colorLimitYellowIc);
|
||||
&.is-limit--upr:before { content: $glyph-icon-arrow-up; }
|
||||
&.is-limit--lwr:before { content: $glyph-icon-arrow-down; }
|
||||
}
|
||||
|
||||
.is-limit--red {
|
||||
@include statusStyle($colorLimitRedBg, $colorLimitRedFg, $colorLimitRedIc);
|
||||
&.is-limit--upr:before { content: $glyph-icon-arrow-double-up; }
|
||||
&.is-limit--lwr:before { content: $glyph-icon-arrow-double-down; }
|
||||
}
|
||||
|
||||
/*************************************************** STATUS */
|
||||
[class*='s-status'] {
|
||||
&:before {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); }
|
||||
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); }
|
||||
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); }
|
||||
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); }
|
||||
.s-status-ok, .s-status-icon-ok { @include elementStatusColors($colorOk); }
|
||||
|
||||
.s-status-icon-warning-hi:before { content: $glyph-icon-alert-triangle; }
|
||||
.s-status-icon-warning-lo:before { content: $glyph-icon-alert-rect; }
|
||||
.s-status-icon-diagnostic:before { content: $glyph-icon-eye-open; }
|
||||
.s-status-icon-info:before { content: $glyph-icon-info; }
|
||||
.s-status-icon-ok:before { content: $glyph-icon-check; }
|
||||
|
||||
/*************************************************** INDICATOR COLORING */
|
||||
.ls-indicator {
|
||||
&.s-status-info {
|
||||
@include indicatorStatusColors($colorInfo);
|
||||
}
|
||||
|
||||
&.s-status-disabled {
|
||||
@include indicatorStatusColors($colorIndicatorDisabled);
|
||||
}
|
||||
|
||||
&.s-status-available {
|
||||
@include indicatorStatusColors($colorIndicatorAvailable);
|
||||
}
|
||||
|
||||
&.s-status-on,
|
||||
&.s-status-enabled {
|
||||
@include indicatorStatusColors($colorIndicatorOn);
|
||||
}
|
||||
|
||||
&.s-status-off {
|
||||
@include indicatorStatusColors($colorIndicatorOff);
|
||||
}
|
||||
|
||||
&.s-status-caution,
|
||||
&.s-status-warning,
|
||||
&.s-status-alert {
|
||||
@include indicatorStatusColors($colorStatusAlert);
|
||||
}
|
||||
|
||||
&.s-status-error {
|
||||
@include indicatorStatusColors($colorStatusError);
|
||||
}
|
||||
}
|
@ -21,15 +21,41 @@
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************** TABLE */
|
||||
table {
|
||||
$minW: 50px;
|
||||
width: 100%;
|
||||
|
||||
thead {
|
||||
background: $colorTabHeaderBg;
|
||||
th + th {
|
||||
border-left: 1px solid $colorTabHeaderBorder;
|
||||
}
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr + tr {
|
||||
border-top: 1px solid $colorTabBorder;
|
||||
}
|
||||
}
|
||||
|
||||
th, td {
|
||||
white-space: nowrap;
|
||||
min-width: $minW;
|
||||
padding: $tabularTdPadTB $tabularTdPadLR;
|
||||
}
|
||||
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.c-table {
|
||||
// Can be used by any type of table, scrolling, LAD, etc.
|
||||
$min-w: 50px;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
justify-content: flex-start;
|
||||
position: absolute;
|
||||
top: 0; right: 0; bottom: 0; left: 0;
|
||||
width: 100%;
|
||||
|
||||
&__control-bar,
|
||||
&__headers-w {
|
||||
@ -37,21 +63,12 @@
|
||||
}
|
||||
|
||||
/******************************* ELEMENTS */
|
||||
th, td {
|
||||
white-space: nowrap;
|
||||
min-width: $min-w;
|
||||
padding: $tabularTdPadTB $tabularTdPadLR;
|
||||
}
|
||||
|
||||
td {
|
||||
color: $colorTelemFresh;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
&__control-bar {
|
||||
margin-bottom: $interiorMarginSm;
|
||||
}
|
||||
|
||||
thead tr,
|
||||
[class*="__header"] {
|
||||
background: $colorTabHeaderBg;
|
||||
|
||||
@ -62,14 +79,20 @@
|
||||
}
|
||||
}
|
||||
|
||||
tbody,
|
||||
&__body {
|
||||
tr {
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid $colorTabBorder;
|
||||
}
|
||||
tr:not(.c-table__group-header) + tr:not(.c-table__group-header) {
|
||||
border-top: 1px solid $colorTabBorder;
|
||||
}
|
||||
}
|
||||
|
||||
&__group-header {
|
||||
// tr element found in LAD Table Sets
|
||||
border-top: 1px solid $colorTabHeaderBorder;
|
||||
background: $colorTabGroupHeaderBg;
|
||||
td { color: $colorTabGroupHeaderFg; }
|
||||
}
|
||||
|
||||
&--sortable {
|
||||
.is-sorting {
|
||||
&:after {
|
||||
@ -88,4 +111,10 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-lad-table {
|
||||
th, td {
|
||||
width: 33%; // Needed to prevent size jumping as values dynamically update
|
||||
}
|
||||
}
|
@ -26,7 +26,10 @@
|
||||
/******************** RENDERS CSS */
|
||||
@import "glyphs";
|
||||
@import "global";
|
||||
@import "status";
|
||||
@import "controls";
|
||||
@import "table";
|
||||
@import "legacy";
|
||||
|
||||
/******************** LEGACY CSS */
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
|
@ -14,7 +14,7 @@
|
||||
//@import "../styles/about";
|
||||
//@import "../styles/text";
|
||||
@import "../styles/icons";
|
||||
@import "../styles/status";
|
||||
//@import "../styles/status";
|
||||
@import "../styles/data-status";
|
||||
@import "../styles/helpers/bubbles";
|
||||
@import "../styles/helpers/splitter";
|
||||
@ -57,8 +57,8 @@
|
||||
//!********************************* VIEWS *!
|
||||
@import "../styles/fixed-position";
|
||||
//@import "../styles/lists/tabular";
|
||||
@import "../styles/plots/plots-main";
|
||||
@import "../styles/plots/legend";
|
||||
//@import "../styles/plots/plots-main";
|
||||
//@import "../styles/plots/legend";
|
||||
@import "../styles/iframe";
|
||||
@import "../styles/views";
|
||||
@import "../styles/items/item";
|
||||
@ -69,11 +69,9 @@
|
||||
//!********************************* TO BE MOVED *!
|
||||
@import "../styles/autoflow";
|
||||
@import "../styles/features/imagery";
|
||||
@import "../styles/features/time-display";
|
||||
//@import "../styles/features/time-display";
|
||||
@import "../styles/widgets";
|
||||
//
|
||||
//!********************************* APP STARTUP *!
|
||||
//@import "../styles/app-start";
|
||||
|
||||
@import "../styles/conductor/time-conductor-snow";
|
||||
//@import "../styles/notebook/notebook-snow";
|
@ -53,7 +53,7 @@
|
||||
}
|
||||
|
||||
> .abs.outer-holder {
|
||||
z-index: 72;
|
||||
z-index: 70;
|
||||
> .abs.inner-holder {
|
||||
$m: $overlayMargin;
|
||||
top: $m;
|
||||
|
5
src/ui/components/COMPONENTS.md
Normal file
5
src/ui/components/COMPONENTS.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Components
|
||||
|
||||
Components in this folder are intended for reuse in other parts of the
|
||||
application. In order for components to be reused, they must not depend on
|
||||
parent styling, and they should have minimum internal state.
|
134
src/ui/components/ObjectFrame.vue
Normal file
134
src/ui/components/ObjectFrame.vue
Normal file
@ -0,0 +1,134 @@
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="u-contents c-so-view has-local-controls"
|
||||
:class="{
|
||||
'c-so-view--no-frame': !hasFrame
|
||||
}">
|
||||
<div class="c-so-view__header">
|
||||
<div class="c-so-view__header__start">
|
||||
<div class="c-so-view__header__name"
|
||||
:class="cssClass">
|
||||
{{ domainObject && domainObject.name }}
|
||||
</div>
|
||||
<context-menu-drop-down
|
||||
:object-path="objectPath">
|
||||
</context-menu-drop-down>
|
||||
</div>
|
||||
<div class="c-so-view__header__end">
|
||||
<div class="c-button icon-expand local-controls--hidden"></div>
|
||||
</div>
|
||||
</div>
|
||||
<object-view class="c-so-view__object-view"
|
||||
:object="domainObject"></object-view>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-so-view {
|
||||
/*************************** HEADER */
|
||||
&__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&__start,
|
||||
&__end {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
&__name {
|
||||
@include headerFont(1em);
|
||||
display: flex;
|
||||
&:before {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&--no-frame .c-so-view__header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__name {
|
||||
@include ellipsize();
|
||||
@include headerFont(1.2em);
|
||||
flex: 0 1 auto;
|
||||
|
||||
&:before {
|
||||
// Object type icon
|
||||
flex: 0 0 auto;
|
||||
margin-right: $interiorMarginSm;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************** OBJECT VIEW */
|
||||
&__object-view {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
|
||||
.c-object-view {
|
||||
.u-fills-container {
|
||||
// Expand component types that fill a container
|
||||
@include abs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ObjectView from './ObjectView.vue'
|
||||
import ContextMenuDropDown from './contextMenuDropDown.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
domainObject: Object,
|
||||
objectPath: Array,
|
||||
hasFrame: Boolean,
|
||||
},
|
||||
computed: {
|
||||
cssClass() {
|
||||
if (!this.domainObject || !this.domainObject.type) {
|
||||
return;
|
||||
}
|
||||
let objectType = this.openmct.types.get(this.domainObject.type);
|
||||
if (!objectType || !objectType.definition) {
|
||||
return; // TODO: return unknown icon type.
|
||||
}
|
||||
return objectType.definition.cssClass;
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ObjectView,
|
||||
ContextMenuDropDown,
|
||||
}
|
||||
}
|
||||
</script>
|
84
src/ui/components/ObjectLabel.vue
Normal file
84
src/ui/components/ObjectLabel.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<a class="c-tree__item__label"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
@click="navigateOrPreview"
|
||||
:href="objectLink">
|
||||
<div class="c-tree__item__type-icon"
|
||||
:class="typeClass"></div>
|
||||
<div class="c-tree__item__name">{{ observedObject.name }}</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ObjectLink from '../mixins/object-link';
|
||||
import ContextMenuGesture from '../mixins/context-menu-gesture';
|
||||
import PreviewAction from '../preview/PreviewAction.js';
|
||||
|
||||
export default {
|
||||
mixins: [ObjectLink, ContextMenuGesture],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
domainObject: Object,
|
||||
objectPath: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
observedObject: this.domainObject
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.observedObject) {
|
||||
let removeListener = this.openmct.objects.observe(this.observedObject, '*', (newObject) => {
|
||||
this.observedObject = newObject;
|
||||
});
|
||||
this.$once('hook:destroyed', removeListener);
|
||||
}
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
},
|
||||
computed: {
|
||||
typeClass() {
|
||||
let type = this.openmct.types.get(this.observedObject.type);
|
||||
if (!type) {
|
||||
return 'icon-object-unknown';
|
||||
}
|
||||
return type.definition.cssClass;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navigateOrPreview(event) {
|
||||
if (this.openmct.editor.isEditing()){
|
||||
event.preventDefault();
|
||||
this.preview();
|
||||
}
|
||||
},
|
||||
preview() {
|
||||
if (this.previewAction.appliesTo(this.objectPath)){
|
||||
this.previewAction.invoke(this.objectPath);
|
||||
}
|
||||
},
|
||||
dragStart(event) {
|
||||
let navigatedObject = this.openmct.router.path[0];
|
||||
let serializedPath = JSON.stringify(this.objectPath);
|
||||
|
||||
/*
|
||||
* Cannot inspect data transfer objects on dragover/dragenter so impossible to determine composability at
|
||||
* that point. If dragged object can be composed by navigated object, then indicate with presence of
|
||||
* 'composable-domain-object' in data transfer
|
||||
*/
|
||||
if (this.openmct.composition.checkPolicy(navigatedObject, this.observedObject)) {
|
||||
event.dataTransfer.setData("openmct/composable-domain-object", JSON.stringify(this.domainObject));
|
||||
}
|
||||
// serialize domain object anyway, because some views can drag-and-drop objects without composition
|
||||
// (eg. notabook.)
|
||||
event.dataTransfer.setData("openmct/domain-object-path", serializedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -88,26 +88,25 @@ export default {
|
||||
this.updateView(immediatelySelect);
|
||||
},
|
||||
onDragOver(event) {
|
||||
event.preventDefault();
|
||||
if (this.hasComposableDomainObject(event)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
},
|
||||
onDrop(event) {
|
||||
let parentObject = this.currentObject;
|
||||
let d = event.dataTransfer.getData("domainObject");
|
||||
|
||||
if (d) {
|
||||
let childObject = JSON.parse(d);
|
||||
|
||||
if (this.openmct.composition.checkPolicy(parentObject, childObject)){
|
||||
if (!this.openmct.editor.isEditing() && parentObject.type !== 'folder'){
|
||||
this.openmct.editor.edit();
|
||||
}
|
||||
parentObject.composition.push(childObject.identifier);
|
||||
this.openmct.objects.mutate(parentObject, 'composition', parentObject.composition);
|
||||
}
|
||||
|
||||
if (this.hasComposableDomainObject(event)) {
|
||||
let composableDomainObject = this.getComposableDomainObject(event);
|
||||
this.currentObject.composition.push(composableDomainObject.identifier);
|
||||
this.openmct.objects.mutate(this.currentObject, 'composition', this.currentObject.composition);
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
hasComposableDomainObject(event) {
|
||||
return event.dataTransfer.types.includes('openmct/composable-domain-object')
|
||||
},
|
||||
getComposableDomainObject(event) {
|
||||
let serializedDomainObject = event.dataTransfer.getData('openmct/composable-domain-object');
|
||||
return JSON.parse(serializedDomainObject);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
<template>
|
||||
<a class="c-tree__item__label"
|
||||
draggable="true"
|
||||
@dragstart="dragStart"
|
||||
:href="objectLink">
|
||||
<div class="c-tree__item__type-icon"
|
||||
:class="typeClass"></div>
|
||||
<div class="c-tree__item__name">{{ observedObject.name }}</div>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import ObjectLink from '../mixins/object-link';
|
||||
import ContextMenuGesture from '../mixins/context-menu-gesture';
|
||||
|
||||
export default {
|
||||
mixins: [ObjectLink, ContextMenuGesture],
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
domainObject: Object
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
observedObject: this.domainObject
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
if (this.observedObject) {
|
||||
let removeListener = this.openmct.objects.observe(this.observedObject, '*', (newObject) => {
|
||||
this.observedObject = newObject;
|
||||
});
|
||||
this.$once('hook:destroyed', removeListener);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
typeClass() {
|
||||
let type = this.openmct.types.get(this.observedObject.type);
|
||||
if (!type) {
|
||||
return 'icon-object-unknown';
|
||||
}
|
||||
return type.definition.cssClass;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
dragStart(event) {
|
||||
event.dataTransfer.setData("domainObject", JSON.stringify(this.observedObject));
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -18,9 +18,6 @@
|
||||
.c-search {
|
||||
@include wrappedInput();
|
||||
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
|
||||
&:before {
|
||||
// Mag glass icon
|
||||
content: $glyph-icon-magnify;
|
||||
@ -35,6 +32,11 @@
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
input[type='search'] {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -16,7 +16,7 @@
|
||||
</li>
|
||||
<li class="js-last-place" @drop="moveToIndex(elements.length)"></li>
|
||||
</ul>
|
||||
<div v-if="elements.length === 0">No contained elements</div>
|
||||
<div v-if="elements.length === 0">No contained elements</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -55,8 +55,8 @@
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import Search from '../controls/search.vue';
|
||||
import ObjectLabel from '../controls/ObjectLabel.vue';
|
||||
import Search from '../components/search.vue';
|
||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
@ -147,7 +147,7 @@ export default {
|
||||
composition.splice(deleteIndex, 1);
|
||||
composition.splice(moveToIndex, 0, moveFromId);
|
||||
}
|
||||
|
||||
|
||||
this.openmct.objects.mutate(this.parentObject, 'composition', composition);
|
||||
},
|
||||
moveFrom(index){
|
||||
@ -155,6 +155,7 @@ export default {
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.selection.off('change', this.showSelection);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -49,6 +49,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
.c-color-swatch {
|
||||
$d: 12px;
|
||||
display: block;
|
||||
flex: 0 0 auto;
|
||||
width: $d;
|
||||
height: $d;
|
||||
}
|
||||
|
||||
/************************************************************** LEGACY */
|
||||
// TODO: refactor when legacy properties markup can be converted
|
||||
.inspector-location {
|
||||
@ -128,9 +136,6 @@
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
+ .c-properties {
|
||||
// Margin between components
|
||||
margin-top: $interiorMarginLg;
|
||||
@ -176,11 +181,32 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
/********************************************* LEGACY SUPPORT */
|
||||
.c-inspector {
|
||||
li.grid-row + li.grid-row {
|
||||
> * {
|
||||
border-top: 1px solid $colorInspectorSectionHeaderBg;
|
||||
}
|
||||
}
|
||||
|
||||
li.grid-row .label {
|
||||
color: $colorInspectorPropName;
|
||||
}
|
||||
|
||||
li.grid-row .value {
|
||||
color: $colorInspectorPropVal;
|
||||
word-break: break-all;
|
||||
&:first-child {
|
||||
// If there is no preceding .label element, make value span columns
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import multipane from '../controls/multipane.vue';
|
||||
import pane from '../controls/pane.vue';
|
||||
import multipane from '../layout/multipane.vue';
|
||||
import pane from '../layout/pane.vue';
|
||||
import Elements from './Elements.vue';
|
||||
import Location from './Location.vue';
|
||||
import Properties from './Properties.vue';
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user