mirror of
https://github.com/nasa/openmct.git
synced 2025-06-28 19:53:02 +00:00
Compare commits
19 Commits
table-colu
...
table-perf
Author | SHA1 | Date | |
---|---|---|---|
a8ebf3d00c | |||
bc5e300ba9 | |||
57efef3160 | |||
dfc5a9f040 | |||
57443d227d | |||
d36441db73 | |||
327782835e | |||
994f6be535 | |||
72fc8a24a5 | |||
07002c12eb | |||
c688d19e15 | |||
c0ce448dc3 | |||
6c479d6d59 | |||
76ba487261 | |||
e3f4da19f9 | |||
c7ffcbf7e0 | |||
a27b3737f1 | |||
78dccf1e0a | |||
9cb7e09aef |
@ -54,6 +54,9 @@
|
||||
openmct.install(openmct.plugins.AutoflowView({
|
||||
type: "telemetry.panel"
|
||||
}));
|
||||
openmct.install(openmct.plugins.DisplayLayout({
|
||||
showAsView: ['summary-widget', 'example.imagery']
|
||||
}));
|
||||
openmct.install(openmct.plugins.Conductor({
|
||||
menuOptions: [
|
||||
{
|
||||
|
@ -31,7 +31,6 @@ define([
|
||||
"./src/navigation/NavigateAction",
|
||||
"./src/navigation/OrphanNavigationHandler",
|
||||
"./src/windowing/NewTabAction",
|
||||
"./src/windowing/WindowTitler",
|
||||
"./res/templates/browse.html",
|
||||
"./res/templates/browse-object.html",
|
||||
"./res/templates/browse/object-header.html",
|
||||
@ -52,7 +51,6 @@ define([
|
||||
NavigateAction,
|
||||
OrphanNavigationHandler,
|
||||
NewTabAction,
|
||||
WindowTitler,
|
||||
browseTemplate,
|
||||
browseObjectTemplate,
|
||||
objectHeaderTemplate,
|
||||
@ -226,14 +224,6 @@ define([
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"implementation": WindowTitler,
|
||||
"depends": [
|
||||
"navigationService",
|
||||
"$rootScope",
|
||||
"$document"
|
||||
]
|
||||
},
|
||||
{
|
||||
"implementation": OrphanNavigationHandler,
|
||||
"depends": [
|
||||
|
@ -1,51 +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 () {
|
||||
|
||||
/**
|
||||
* Updates the title of the current window to reflect the name
|
||||
* of the currently navigated-to domain object.
|
||||
* @memberof platform/commonUI/browse
|
||||
* @constructor
|
||||
*/
|
||||
function WindowTitler(navigationService, $rootScope, $document) {
|
||||
// Look up name of the navigated domain object...
|
||||
function getNavigatedObjectName() {
|
||||
var navigatedObject = navigationService.getNavigation();
|
||||
return navigatedObject && navigatedObject.getModel().name;
|
||||
}
|
||||
|
||||
// Set the window title...
|
||||
function setTitle(name) {
|
||||
$document[0].title = name;
|
||||
}
|
||||
|
||||
// Watch the former, and invoke the latter
|
||||
$rootScope.$watch(getNavigatedObjectName, setTitle);
|
||||
}
|
||||
|
||||
return WindowTitler;
|
||||
}
|
||||
);
|
@ -1,78 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
/**
|
||||
* WindowTitlerSpec. Created by vwoeltje on 11/6/14.
|
||||
*/
|
||||
define(
|
||||
["../../src/windowing/WindowTitler"],
|
||||
function (WindowTitler) {
|
||||
|
||||
describe("The window titler", function () {
|
||||
var mockNavigationService,
|
||||
mockRootScope,
|
||||
mockDocument,
|
||||
mockDomainObject,
|
||||
titler; // eslint-disable-line
|
||||
|
||||
beforeEach(function () {
|
||||
mockNavigationService = jasmine.createSpyObj(
|
||||
'navigationService',
|
||||
['getNavigation']
|
||||
);
|
||||
mockRootScope = jasmine.createSpyObj(
|
||||
'$rootScope',
|
||||
['$watch']
|
||||
);
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
'domainObject',
|
||||
['getModel']
|
||||
);
|
||||
mockDocument = [{}];
|
||||
|
||||
mockDomainObject.getModel.and.returnValue({ name: 'Test name' });
|
||||
mockNavigationService.getNavigation.and.returnValue(mockDomainObject);
|
||||
|
||||
titler = new WindowTitler(
|
||||
mockNavigationService,
|
||||
mockRootScope,
|
||||
mockDocument
|
||||
);
|
||||
});
|
||||
|
||||
it("listens for changes to the name of the navigated object", function () {
|
||||
expect(mockRootScope.$watch).toHaveBeenCalledWith(
|
||||
jasmine.any(Function),
|
||||
jasmine.any(Function)
|
||||
);
|
||||
expect(mockRootScope.$watch.calls.mostRecent().args[0]())
|
||||
.toEqual('Test name');
|
||||
});
|
||||
|
||||
it("sets the title to the name of the navigated object", function () {
|
||||
mockRootScope.$watch.calls.mostRecent().args[1]("Some name");
|
||||
expect(mockDocument[0].title).toEqual("Some name");
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
@ -162,9 +162,6 @@ function (
|
||||
function saveAfterClone(clonedObject) {
|
||||
return this.openmct.editor.save().then(() => {
|
||||
// Force mutation for search indexing
|
||||
clonedObject.useCapability('mutation', (model) => {
|
||||
return model;
|
||||
});
|
||||
return clonedObject;
|
||||
})
|
||||
}
|
||||
@ -173,6 +170,14 @@ function (
|
||||
return fetchObject(clonedObject.getId())
|
||||
}
|
||||
|
||||
function indexForSearch(savedObject) {
|
||||
savedObject.useCapability('mutation', (model) => {
|
||||
return model;
|
||||
});
|
||||
|
||||
return savedObject;
|
||||
}
|
||||
|
||||
function onSuccess(object) {
|
||||
self.notificationService.info("Save Succeeded");
|
||||
return object;
|
||||
@ -194,6 +199,7 @@ function (
|
||||
.then(undirtyOriginals)
|
||||
.then(saveAfterClone)
|
||||
.then(finishEditing)
|
||||
.then(indexForSearch)
|
||||
.then(hideBlockingDialog)
|
||||
.then(onSuccess)
|
||||
.catch(onFailure);
|
||||
|
@ -71,6 +71,12 @@ define(
|
||||
openmct.editor.cancel();
|
||||
}
|
||||
|
||||
function isFirstViewEditable(domainObject) {
|
||||
let firstView = openmct.objectViews.get(domainObject)[0];
|
||||
|
||||
return firstView && firstView.canEdit && firstView.canEdit(domainObject);
|
||||
}
|
||||
|
||||
function navigateAndEdit(object) {
|
||||
let objectPath = object.getCapability('context').getPath(),
|
||||
url = '#/browse/' + objectPath
|
||||
@ -82,7 +88,9 @@ define(
|
||||
|
||||
window.location.href = url;
|
||||
|
||||
openmct.editor.edit();
|
||||
if (isFirstViewEditable(object.useCapability('adapter'))) {
|
||||
openmct.editor.edit();
|
||||
}
|
||||
}
|
||||
|
||||
newModel.type = this.type.getKey();
|
||||
|
@ -37,75 +37,17 @@ define(
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle persistence failures by providing the user with a
|
||||
* dialog summarizing these failures, and giving the option
|
||||
* to overwrite/cancel as appropriate.
|
||||
* Discard failures
|
||||
* @param {Array} failures persistence failures, as prepared
|
||||
* by PersistenceQueueHandler
|
||||
* @memberof platform/persistence/queue.PersistenceFailureHandler#
|
||||
*/
|
||||
PersistenceFailureHandler.prototype.handle = function handleFailures(failures) {
|
||||
// Prepare dialog for display
|
||||
|
||||
var dialogModel = new PersistenceFailureDialog(failures),
|
||||
revisionErrors = dialogModel.model.revised,
|
||||
$q = this.$q;
|
||||
|
||||
// Refresh revision information for the domain object associated
|
||||
// with this persistence failure
|
||||
function refresh(failure) {
|
||||
// Refresh the domain object to the latest from persistence
|
||||
return failure.persistence.refresh();
|
||||
}
|
||||
|
||||
// Issue a new persist call for the domain object associated with
|
||||
// this failure.
|
||||
function persist(failure) {
|
||||
// Note that we reissue the persist request here, but don't
|
||||
// return it, to avoid a circular wait. We trust that the
|
||||
// PersistenceQueue will behave correctly on the next round
|
||||
// of flushing.
|
||||
failure.requeue();
|
||||
}
|
||||
|
||||
// Retry persistence (overwrite) for this set of failed attempts
|
||||
function retry(failuresToRetry) {
|
||||
var models = {};
|
||||
|
||||
// Cache a copy of the model
|
||||
function cacheModel(failure) {
|
||||
// Clone...
|
||||
models[failure.id] = JSON.parse(JSON.stringify(
|
||||
failure.domainObject.getModel()
|
||||
));
|
||||
}
|
||||
|
||||
// Mutate a domain object to restore its model
|
||||
function remutate(failure) {
|
||||
var model = models[failure.id];
|
||||
return failure.domainObject.useCapability(
|
||||
"mutation",
|
||||
function () {
|
||||
return model;
|
||||
},
|
||||
model.modified
|
||||
);
|
||||
}
|
||||
|
||||
// Cache the object models we might want to save
|
||||
failuresToRetry.forEach(cacheModel);
|
||||
|
||||
// Strategy here:
|
||||
// * Cache all of the models we might want to save (above)
|
||||
// * Refresh all domain objects (so they are latest versions)
|
||||
// * Re-insert the cached domain object models
|
||||
// * Invoke persistence again
|
||||
return $q.all(failuresToRetry.map(refresh)).then(function () {
|
||||
return $q.all(failuresToRetry.map(remutate));
|
||||
}).then(function () {
|
||||
return $q.all(failuresToRetry.map(persist));
|
||||
});
|
||||
}
|
||||
|
||||
// Discard changes for a failed refresh
|
||||
function discard(failure) {
|
||||
var persistence =
|
||||
@ -118,19 +60,7 @@ define(
|
||||
return $q.all(failuresToDiscard.map(discard));
|
||||
}
|
||||
|
||||
// Handle user input (did they choose to overwrite?)
|
||||
function handleChoice(key) {
|
||||
// If so, try again
|
||||
if (key === PersistenceFailureConstants.OVERWRITE_KEY) {
|
||||
return retry(revisionErrors);
|
||||
} else {
|
||||
return discardAll(revisionErrors);
|
||||
}
|
||||
}
|
||||
|
||||
// Prompt for user input, the overwrite if they said so.
|
||||
return this.dialogService.getUserChoice(dialogModel)
|
||||
.then(handleChoice, handleChoice);
|
||||
return discardAll(revisionErrors);
|
||||
};
|
||||
|
||||
return PersistenceFailureHandler;
|
||||
|
@ -74,43 +74,14 @@ define(
|
||||
handler = new PersistenceFailureHandler(mockQ, mockDialogService);
|
||||
});
|
||||
|
||||
it("shows a dialog to handle failures", function () {
|
||||
it("discards on handle", function () {
|
||||
handler.handle(mockFailures);
|
||||
expect(mockDialogService.getUserChoice).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("overwrites on request", function () {
|
||||
mockQ.all.and.returnValue(asPromise([]));
|
||||
handler.handle(mockFailures);
|
||||
// User chooses overwrite
|
||||
mockPromise.then.calls.mostRecent().args[0](Constants.OVERWRITE_KEY);
|
||||
// Should refresh, remutate, and requeue all objects
|
||||
mockFailures.forEach(function (mockFailure, i) {
|
||||
expect(mockFailure.persistence.refresh).toHaveBeenCalled();
|
||||
expect(mockFailure.requeue).toHaveBeenCalled();
|
||||
expect(mockFailure.domainObject.useCapability).toHaveBeenCalledWith(
|
||||
'mutation',
|
||||
jasmine.any(Function),
|
||||
i // timestamp
|
||||
);
|
||||
expect(mockFailure.domainObject.useCapability.calls.mostRecent().args[1]())
|
||||
.toEqual({ id: mockFailure.id, modified: i });
|
||||
});
|
||||
});
|
||||
|
||||
it("discards on request", function () {
|
||||
mockQ.all.and.returnValue(asPromise([]));
|
||||
handler.handle(mockFailures);
|
||||
// User chooses overwrite
|
||||
mockPromise.then.calls.mostRecent().args[0](false);
|
||||
// Should refresh, but not remutate, and requeue all objects
|
||||
mockFailures.forEach(function (mockFailure) {
|
||||
expect(mockFailure.persistence.refresh).toHaveBeenCalled();
|
||||
expect(mockFailure.requeue).not.toHaveBeenCalled();
|
||||
expect(mockFailure.domainObject.useCapability).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
);
|
||||
|
@ -248,7 +248,6 @@ define([
|
||||
this.legacyRegistry = defaultRegistry;
|
||||
this.install(this.plugins.Plot());
|
||||
this.install(this.plugins.TelemetryTable());
|
||||
this.install(this.plugins.DisplayLayout());
|
||||
this.install(PreviewPlugin.default());
|
||||
this.install(LegacyIndicatorsPlugin());
|
||||
this.install(LicensesPlugin.default());
|
||||
@ -257,7 +256,6 @@ define([
|
||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
MCT.prototype = Object.create(EventEmitter.prototype);
|
||||
@ -328,6 +326,12 @@ define([
|
||||
* MCT; if undefined, MCT will be run in the body of the document
|
||||
*/
|
||||
MCT.prototype.start = function (domElement) {
|
||||
if (!this.plugins.DisplayLayout._installed) {
|
||||
this.install(this.plugins.DisplayLayout({
|
||||
showAsView: ['summary-widget']
|
||||
}));
|
||||
}
|
||||
|
||||
if (!domElement) {
|
||||
domElement = document.body;
|
||||
}
|
||||
|
@ -137,8 +137,7 @@ define([
|
||||
function callbackWrapper(series) {
|
||||
callback(createDatum(domainObject, metadata, series, series.getPointCount() - 1));
|
||||
}
|
||||
|
||||
return capability.subscribe(callbackWrapper, request);
|
||||
return capability.subscribe(callbackWrapper, request) || function () {};
|
||||
};
|
||||
|
||||
LegacyTelemetryProvider.prototype.supportsLimits = function (domainObject) {
|
||||
|
@ -36,7 +36,7 @@
|
||||
|
||||
.c-message {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
align-items: center;
|
||||
|
||||
> * + * {
|
||||
margin-left: $interiorMarginLg;
|
||||
@ -66,6 +66,17 @@
|
||||
font-size: 1.2em; // TEMP
|
||||
}
|
||||
|
||||
&--simple {
|
||||
// Icon and text elements only
|
||||
&:before {
|
||||
font-size: 30px !important;
|
||||
}
|
||||
|
||||
[class*='__text'] {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
/************************** LEGACY */
|
||||
&.message-severity-info:before {
|
||||
@include legacyMessage();
|
||||
|
@ -152,7 +152,7 @@
|
||||
return this.internalDomainObject.configuration.items;
|
||||
}
|
||||
},
|
||||
inject: ['openmct'],
|
||||
inject: ['openmct', 'options'],
|
||||
props: ['domainObject'],
|
||||
components: ITEM_TYPE_VIEW_MAP,
|
||||
methods: {
|
||||
@ -283,9 +283,8 @@
|
||||
}
|
||||
},
|
||||
isTelemetry(domainObject) {
|
||||
if (this.openmct.telemetry.isTelemetryObject(domainObject)
|
||||
&& domainObject.type !== 'summary-widget'
|
||||
&& domainObject.type !== 'example.imagery') {
|
||||
if (this.openmct.telemetry.isTelemetryObject(domainObject) &&
|
||||
!this.options.showAsView.includes(domainObject.type)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -25,8 +25,7 @@ import Vue from 'vue'
|
||||
import objectUtils from '../../api/objects/object-utils.js'
|
||||
import DisplayLayoutType from './DisplayLayoutType.js'
|
||||
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
|
||||
|
||||
export default function () {
|
||||
export default function DisplayLayoutPlugin(options) {
|
||||
return function (openmct) {
|
||||
openmct.objectViews.addProvider({
|
||||
key: 'layout.view',
|
||||
@ -47,7 +46,8 @@ export default function () {
|
||||
template: '<layout ref="displayLayout" :domain-object="domainObject"></layout>',
|
||||
provide: {
|
||||
openmct,
|
||||
objectUtils
|
||||
objectUtils,
|
||||
options
|
||||
},
|
||||
el: container,
|
||||
data () {
|
||||
@ -83,5 +83,6 @@ export default function () {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
DisplayLayoutPlugin._installed = true;
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,11 @@
|
||||
<span class="c-disclosure-triangle is-enabled flex-elem"
|
||||
:class="{'c-disclosure-triangle--expanded': expanded}"></span>
|
||||
<div class="c-tree__item__label">
|
||||
<div class="t-object-label l-flex-row flex-elem grows">
|
||||
<div class="t-item-icon flex-elem"
|
||||
<div class="c-object-label">
|
||||
<div class="c-object-label__type-icon"
|
||||
:class="objectCssClass">
|
||||
</div>
|
||||
<div class="t-title-label flex-elem grows">{{ filterObject.name }}</div>
|
||||
<div class="c-object-label__name flex-elem grows">{{ filterObject.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -25,176 +25,220 @@ define([
|
||||
], function (
|
||||
uuid
|
||||
) {
|
||||
function isTelemetry(domainObject) {
|
||||
if (openmct.telemetry.isTelemetryObject(domainObject)
|
||||
&& domainObject.type !== 'summary-widget'
|
||||
&& domainObject.type !== 'example.imagery') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function migrateDisplayLayout(domainObject, childObjects) {
|
||||
const DEFAULT_GRID_SIZE = [32, 32];
|
||||
let migratedObject = Object.assign({}, domainObject);
|
||||
let panels = migratedObject.configuration.layout.panels;
|
||||
let items = [];
|
||||
|
||||
Object.keys(panels).forEach(key => {
|
||||
let panel = panels[key];
|
||||
let domainObject = childObjects[key];
|
||||
|
||||
if (isTelemetry(domainObject)) {
|
||||
items.push({
|
||||
width: panel.dimensions[0],
|
||||
height: panel.dimensions[1],
|
||||
x: panel.position[0],
|
||||
y: panel.position[1],
|
||||
useGrid: true,
|
||||
identifier: domainObject.identifier,
|
||||
id: uuid(),
|
||||
type: 'telemetry-view',
|
||||
displayMode: 'all',
|
||||
value: openmct.telemetry.getMetadata(domainObject).getDefaultDisplayValue(),
|
||||
stroke: "transparent",
|
||||
fill: "",
|
||||
color: "",
|
||||
size: "13px"
|
||||
return function Migrations(openmct) {
|
||||
function getColumnNameKeyMap(domainObject) {
|
||||
let composition = openmct.composition.get(domainObject);
|
||||
if (composition) {
|
||||
return composition.load().then(composees => {
|
||||
return composees.reduce((nameKeyMap, composee) => {
|
||||
let metadata = openmct.telemetry.getMetadata(composee);
|
||||
if (metadata !== undefined) {
|
||||
metadata.values().forEach(value => {
|
||||
nameKeyMap[value.name] = value.key;
|
||||
});
|
||||
}
|
||||
return nameKeyMap;
|
||||
}, {});
|
||||
});
|
||||
} else {
|
||||
items.push({
|
||||
width: panel.dimensions[0],
|
||||
height: panel.dimensions[1],
|
||||
x: panel.position[0],
|
||||
y: panel.position[1],
|
||||
useGrid: true,
|
||||
identifier: domainObject.identifier,
|
||||
id: uuid(),
|
||||
type: 'subobject-view',
|
||||
hasFrame: panel.hasFrame
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
migratedObject.configuration.items = items;
|
||||
migratedObject.configuration.layoutGrid = migratedObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||
delete migratedObject.layoutGrid;
|
||||
delete migratedObject.configuration.layout;
|
||||
return migratedObject;
|
||||
}
|
||||
|
||||
function migrateFixedPositionConfiguration(elements, telemetryObjects) {
|
||||
const DEFAULT_STROKE = "transparent";
|
||||
const DEFAULT_SIZE = "13px";
|
||||
const DEFAULT_COLOR = "";
|
||||
const DEFAULT_FILL = "";
|
||||
let items = [];
|
||||
|
||||
elements.forEach(element => {
|
||||
let item = {
|
||||
x: element.x,
|
||||
y: element.y,
|
||||
width: element.width,
|
||||
height: element.height,
|
||||
useGrid: element.useGrid,
|
||||
id: uuid()
|
||||
};
|
||||
|
||||
if (element.type === "fixed.telemetry") {
|
||||
item.type = "telemetry-view";
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
item.color = element.color || DEFAULT_COLOR;
|
||||
item.size = element.size || DEFAULT_SIZE;
|
||||
item.identifier = telemetryObjects[element.id].identifier;
|
||||
item.displayMode = element.titled ? 'all' : 'value';
|
||||
item.value = openmct.telemetry.getMetadata(telemetryObjects[element.id]).getDefaultDisplayValue();
|
||||
} else if (element.type === 'fixed.box') {
|
||||
item.type = "box-view";
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
} else if (element.type === 'fixed.line') {
|
||||
item.type = "line-view";
|
||||
item.x2 = element.x2;
|
||||
item.y2 = element.y2;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
delete item.height;
|
||||
delete item.width;
|
||||
} else if (element.type === 'fixed.text') {
|
||||
item.type = "text-view";
|
||||
item.text = element.text;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
item.color = element.color || DEFAULT_COLOR;
|
||||
item.size = element.size || DEFAULT_SIZE;
|
||||
} else if (element.type === 'fixed.image') {
|
||||
item.type = "image-view";
|
||||
item.url =element.url;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
}
|
||||
|
||||
items.push(item);
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
check(domainObject) {
|
||||
return domainObject.type === 'layout' && domainObject.configuration.layout;
|
||||
},
|
||||
migrate(domainObject) {
|
||||
let childObjects = {};
|
||||
let promises = Object.keys(domainObject.configuration.layout.panels).map(key => {
|
||||
return openmct.objects.get(key)
|
||||
.then(object => {
|
||||
childObjects[key] = object;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function () {
|
||||
return migrateDisplayLayout(domainObject, childObjects);
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
check(domainObject) {
|
||||
return domainObject.type === 'telemetry.fixed' && domainObject.configuration['fixed-display'];
|
||||
},
|
||||
migrate(domainObject) {
|
||||
const DEFAULT_GRID_SIZE = [64, 16];
|
||||
let newLayoutObject = {
|
||||
identifier: domainObject.identifier,
|
||||
location: domainObject.location,
|
||||
name: domainObject.name,
|
||||
type: "layout"
|
||||
};
|
||||
let layoutType = openmct.types.get('layout');
|
||||
layoutType.definition.initialize(newLayoutObject);
|
||||
newLayoutObject.composition = domainObject.composition;
|
||||
newLayoutObject.configuration.layoutGrid = domainObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||
|
||||
let elements = domainObject.configuration['fixed-display'].elements;
|
||||
let telemetryObjects = {};
|
||||
let promises = elements.map(element => {
|
||||
if (element.id) {
|
||||
return openmct.objects.get(element.id)
|
||||
.then(object => {
|
||||
telemetryObjects[element.id] = object;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function () {
|
||||
newLayoutObject.configuration.items =
|
||||
migrateFixedPositionConfiguration(elements, telemetryObjects);
|
||||
return newLayoutObject;
|
||||
});
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
function isTelemetry(domainObject) {
|
||||
if (openmct.telemetry.isTelemetryObject(domainObject)
|
||||
&& domainObject.type !== 'summary-widget'
|
||||
&& domainObject.type !== 'example.imagery') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function migrateDisplayLayout(domainObject, childObjects) {
|
||||
const DEFAULT_GRID_SIZE = [32, 32];
|
||||
let migratedObject = Object.assign({}, domainObject);
|
||||
let panels = migratedObject.configuration.layout.panels;
|
||||
let items = [];
|
||||
|
||||
Object.keys(panels).forEach(key => {
|
||||
let panel = panels[key];
|
||||
let domainObject = childObjects[key];
|
||||
|
||||
if (isTelemetry(domainObject)) {
|
||||
items.push({
|
||||
width: panel.dimensions[0],
|
||||
height: panel.dimensions[1],
|
||||
x: panel.position[0],
|
||||
y: panel.position[1],
|
||||
useGrid: true,
|
||||
identifier: domainObject.identifier,
|
||||
id: uuid(),
|
||||
type: 'telemetry-view',
|
||||
displayMode: 'all',
|
||||
value: openmct.telemetry.getMetadata(domainObject).getDefaultDisplayValue(),
|
||||
stroke: "transparent",
|
||||
fill: "",
|
||||
color: "",
|
||||
size: "13px"
|
||||
});
|
||||
} else {
|
||||
items.push({
|
||||
width: panel.dimensions[0],
|
||||
height: panel.dimensions[1],
|
||||
x: panel.position[0],
|
||||
y: panel.position[1],
|
||||
useGrid: true,
|
||||
identifier: domainObject.identifier,
|
||||
id: uuid(),
|
||||
type: 'subobject-view',
|
||||
hasFrame: panel.hasFrame
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
migratedObject.configuration.items = items;
|
||||
migratedObject.configuration.layoutGrid = migratedObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||
delete migratedObject.layoutGrid;
|
||||
delete migratedObject.configuration.layout;
|
||||
return migratedObject;
|
||||
}
|
||||
|
||||
function migrateFixedPositionConfiguration(elements, telemetryObjects) {
|
||||
const DEFAULT_STROKE = "transparent";
|
||||
const DEFAULT_SIZE = "13px";
|
||||
const DEFAULT_COLOR = "";
|
||||
const DEFAULT_FILL = "";
|
||||
let items = [];
|
||||
|
||||
elements.forEach(element => {
|
||||
let item = {
|
||||
x: element.x,
|
||||
y: element.y,
|
||||
width: element.width,
|
||||
height: element.height,
|
||||
useGrid: element.useGrid,
|
||||
id: uuid()
|
||||
};
|
||||
|
||||
if (element.type === "fixed.telemetry") {
|
||||
item.type = "telemetry-view";
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
item.color = element.color || DEFAULT_COLOR;
|
||||
item.size = element.size || DEFAULT_SIZE;
|
||||
item.identifier = telemetryObjects[element.id].identifier;
|
||||
item.displayMode = element.titled ? 'all' : 'value';
|
||||
item.value = openmct.telemetry.getMetadata(telemetryObjects[element.id]).getDefaultDisplayValue();
|
||||
} else if (element.type === 'fixed.box') {
|
||||
item.type = "box-view";
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
} else if (element.type === 'fixed.line') {
|
||||
item.type = "line-view";
|
||||
item.x2 = element.x2;
|
||||
item.y2 = element.y2;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
delete item.height;
|
||||
delete item.width;
|
||||
} else if (element.type === 'fixed.text') {
|
||||
item.type = "text-view";
|
||||
item.text = element.text;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
item.fill = element.fill || DEFAULT_FILL;
|
||||
item.color = element.color || DEFAULT_COLOR;
|
||||
item.size = element.size || DEFAULT_SIZE;
|
||||
} else if (element.type === 'fixed.image') {
|
||||
item.type = "image-view";
|
||||
item.url =element.url;
|
||||
item.stroke = element.stroke || DEFAULT_STROKE;
|
||||
}
|
||||
|
||||
items.push(item);
|
||||
});
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
check(domainObject) {
|
||||
return domainObject.type === 'layout' && domainObject.configuration.layout;
|
||||
},
|
||||
migrate(domainObject) {
|
||||
let childObjects = {};
|
||||
let promises = Object.keys(domainObject.configuration.layout.panels).map(key => {
|
||||
return openmct.objects.get(key)
|
||||
.then(object => {
|
||||
childObjects[key] = object;
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function () {
|
||||
return migrateDisplayLayout(domainObject, childObjects);
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
check(domainObject) {
|
||||
return domainObject.type === 'telemetry.fixed' && domainObject.configuration['fixed-display'];
|
||||
},
|
||||
migrate(domainObject) {
|
||||
const DEFAULT_GRID_SIZE = [64, 16];
|
||||
let newLayoutObject = {
|
||||
identifier: domainObject.identifier,
|
||||
location: domainObject.location,
|
||||
name: domainObject.name,
|
||||
type: "layout"
|
||||
};
|
||||
let layoutType = openmct.types.get('layout');
|
||||
layoutType.definition.initialize(newLayoutObject);
|
||||
newLayoutObject.composition = domainObject.composition;
|
||||
newLayoutObject.configuration.layoutGrid = domainObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||
|
||||
let elements = domainObject.configuration['fixed-display'].elements;
|
||||
let telemetryObjects = {};
|
||||
let promises = elements.map(element => {
|
||||
if (element.id) {
|
||||
return openmct.objects.get(element.id)
|
||||
.then(object => {
|
||||
telemetryObjects[element.id] = object;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function () {
|
||||
newLayoutObject.configuration.items =
|
||||
migrateFixedPositionConfiguration(elements, telemetryObjects);
|
||||
return newLayoutObject;
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
check(domainObject) {
|
||||
return domainObject.type === 'table' &&
|
||||
domainObject.configuration.table;
|
||||
},
|
||||
migrate(domainObject) {
|
||||
let currentTableConfiguration = domainObject.configuration.table || {};
|
||||
let currentColumnConfiguration = currentTableConfiguration.columns || {};
|
||||
return getColumnNameKeyMap(domainObject).then(nameKeyMap => {
|
||||
let hiddenColumns = Object.keys(currentColumnConfiguration).filter(columnName => {
|
||||
return currentColumnConfiguration[columnName] === false;
|
||||
}).reduce((hiddenColumnsMap, hiddenColumnName) => {
|
||||
let key = nameKeyMap[hiddenColumnName];
|
||||
hiddenColumnsMap[key] = true;
|
||||
return hiddenColumnsMap;
|
||||
}, {});
|
||||
|
||||
domainObject.configuration.hiddenColumns = hiddenColumns;
|
||||
delete domainObject.configuration.table;
|
||||
return domainObject;
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
});
|
||||
|
@ -20,19 +20,21 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
import migrations from './Migrations.js'
|
||||
import Migrations from './Migrations.js'
|
||||
|
||||
export default function () {
|
||||
function needsMigration(domainObject) {
|
||||
return migrations.some(m => m.check(domainObject));
|
||||
}
|
||||
|
||||
function migrateObject(domainObject) {
|
||||
return migrations.filter(m => m.check(domainObject))[0]
|
||||
.migrate(domainObject);
|
||||
}
|
||||
|
||||
return function (openmct) {
|
||||
let migrations = Migrations(openmct);
|
||||
|
||||
function needsMigration(domainObject) {
|
||||
return migrations.some(m => m.check(domainObject));
|
||||
}
|
||||
|
||||
function migrateObject(domainObject) {
|
||||
return migrations.filter(m => m.check(domainObject))[0]
|
||||
.migrate(domainObject);
|
||||
}
|
||||
|
||||
let wrappedFunction = openmct.objects.get;
|
||||
openmct.objects.get = function migrate(identifier) {
|
||||
return wrappedFunction.apply(openmct.objects, [identifier])
|
||||
@ -46,6 +48,6 @@ export default function () {
|
||||
}
|
||||
return object;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,6 @@ define([
|
||||
PlotOptionsController.prototype.addSeries = function (series, index) {
|
||||
this.$scope.plotSeries[index] = series;
|
||||
series.locateOldObject(this.$scope.domainObject);
|
||||
|
||||
};
|
||||
|
||||
PlotOptionsController.prototype.resetAllSeries = function (series, index) {
|
||||
|
@ -315,6 +315,7 @@ define([
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.wheelZoom = function (event) {
|
||||
const ZOOM_AMT = 0.1;
|
||||
event.preventDefault();
|
||||
|
||||
if (!this.positionOverPlot) {
|
||||
@ -349,24 +350,24 @@ define([
|
||||
if (event.wheelDelta < 0) {
|
||||
|
||||
this.$scope.xAxis.set('displayRange', {
|
||||
min: xDisplayRange.min + ((xAxisDist * 0.01) * xAxisMinDist),
|
||||
max: xDisplayRange.max - ((xAxisDist * 0.01) * xAxisMaxDist)
|
||||
min: xDisplayRange.min + ((xAxisDist * ZOOM_AMT) * xAxisMinDist),
|
||||
max: xDisplayRange.max - ((xAxisDist * ZOOM_AMT) * xAxisMaxDist)
|
||||
});
|
||||
|
||||
this.$scope.yAxis.set('displayRange', {
|
||||
min: yDisplayRange.min + ((yAxisDist * 0.01) * yAxisMinDist),
|
||||
max: yDisplayRange.max - ((yAxisDist * 0.01) * yAxisMaxDist)
|
||||
min: yDisplayRange.min + ((yAxisDist * ZOOM_AMT) * yAxisMinDist),
|
||||
max: yDisplayRange.max - ((yAxisDist * ZOOM_AMT) * yAxisMaxDist)
|
||||
});
|
||||
} else if (event.wheelDelta >= 0) {
|
||||
|
||||
this.$scope.xAxis.set('displayRange', {
|
||||
min: xDisplayRange.min - ((xAxisDist * 0.01) * xAxisMinDist),
|
||||
max: xDisplayRange.max + ((xAxisDist * 0.01) * xAxisMaxDist)
|
||||
min: xDisplayRange.min - ((xAxisDist * ZOOM_AMT) * xAxisMinDist),
|
||||
max: xDisplayRange.max + ((xAxisDist * ZOOM_AMT) * xAxisMaxDist)
|
||||
});
|
||||
|
||||
this.$scope.yAxis.set('displayRange', {
|
||||
min: yDisplayRange.min - ((yAxisDist * 0.01) * yAxisMinDist),
|
||||
max: yDisplayRange.max + ((yAxisDist * 0.01) * yAxisMaxDist)
|
||||
min: yDisplayRange.min - ((yAxisDist * ZOOM_AMT) * yAxisMinDist),
|
||||
max: yDisplayRange.max + ((yAxisDist * ZOOM_AMT) * yAxisMaxDist)
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -219,6 +219,7 @@ define([
|
||||
|
||||
PlotController.prototype.stopLoading = function () {
|
||||
this.$scope.pending -= 1;
|
||||
this.$scope.$digest();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -88,13 +88,10 @@ export default class RemoveAction {
|
||||
}
|
||||
|
||||
appliesTo(objectPath) {
|
||||
let object = objectPath[0];
|
||||
let objectType = object && this.openmct.types.get(object.type);
|
||||
let parent = objectPath[1];
|
||||
let parentType = parent && this.openmct.types.get(parent.type);
|
||||
|
||||
return objectType.definition.creatable &&
|
||||
parentType &&
|
||||
return parentType &&
|
||||
parentType.definition.creatable &&
|
||||
Array.isArray(parent.composition);
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
<span class="t-configuration"> </span>
|
||||
<span class="t-value-inputs"> </span>
|
||||
</span>
|
||||
<span class="flex-elem local-control local-controls-hidden l-condition-action-buttons-wrapper">
|
||||
<span class="flex-elem c-local-controls--show-on-hover l-condition-action-buttons-wrapper">
|
||||
<a class="s-icon-button icon-duplicate t-duplicate" title="Duplicate this condition"></a>
|
||||
<a class="s-icon-button icon-trash t-delete" title="Delete this condition"></a>
|
||||
</span>
|
||||
|
@ -1,5 +1,5 @@
|
||||
<div class="c-sw-rule">
|
||||
<div class="c-sw-rule__ui l-compact-form has-local-controls l-widget-rule s-widget-rule">
|
||||
<div class="c-sw-rule__ui l-compact-form l-widget-rule s-widget-rule has-local-controls">
|
||||
<div class="c-sw-rule__ui__header widget-rule-header">
|
||||
<div class="c-sw-rule__grippy-wrapper">
|
||||
<div class="c-sw-rule__grippy t-grippy local-control local-controls-hidden"></div>
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="flex-elem rule-title">Default Title</div>
|
||||
<div class="flex-elem rule-description grows">Rule description goes here</div>
|
||||
<div class="flex-elem local-control local-controls-hidden l-rule-action-buttons-wrapper">
|
||||
<div class="flex-elem c-local-controls--show-on-hover l-rule-action-buttons-wrapper">
|
||||
<a class="s-icon-button icon-duplicate t-duplicate" title="Duplicate this rule"></a>
|
||||
<a class="s-icon-button icon-trash t-delete" title="Delete this rule"></a>
|
||||
</div>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<span class="equal-to hidden"> equal to </span>
|
||||
<span class="t-value-inputs"></span>
|
||||
</span>
|
||||
<span class="flex-elem local-control local-controls-hidden l-widget-test-data-item-action-buttons-wrapper">
|
||||
<span class="flex-elem c-local-controls--show-on-hover l-widget-test-data-item-action-buttons-wrapper">
|
||||
<a class="s-icon-button icon-duplicate t-duplicate" title="Duplicate this test value"></a>
|
||||
<a class="s-icon-button icon-trash t-delete" title="Delete this test value"></a>
|
||||
</span>
|
||||
|
@ -3,11 +3,9 @@
|
||||
<div id="widgetIcon" class="c-sw__icon js-sw__icon"></div>
|
||||
<div id="widgetLabel" class="label widget-label c-sw__label js-sw__label">Default Static Name</div>
|
||||
</a>
|
||||
<div class="c-summary-widget__message holder flex-elem t-message-inline c-message message-severity-alert t-message-widget-no-data">
|
||||
<div class="w-message-contents l-message-body-only">
|
||||
<div class="message-body">
|
||||
You must add at least one telemetry object to edit this widget.
|
||||
</div>
|
||||
<div class="js-summary-widget__message c-summary-widget__message c-message c-message--simple message-severity-alert">
|
||||
<div class="c-summary-widget__text">
|
||||
You must add at least one telemetry object to edit this widget.
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-sw-edit__ui holder l-flex-accordion flex-elem grows widget-edit-holder expanded-widget-test-data expanded-widget-rules">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="c-tabs-view">
|
||||
<div class="c-tabs-view__tabs-holder c-compact-button-holder"
|
||||
<div class="c-tabs-view__tabs-holder c-tabs"
|
||||
:class="{
|
||||
'is-dragging': isDragging,
|
||||
'is-mouse-over': allowDrop
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="c-tabs-view__empty-message"
|
||||
v-if="!tabsList.length > 0">Drag objects here to add them to this view.</div>
|
||||
<button class="c-tabs-view__tab c-compact-button"
|
||||
<button class="c-tabs-view__tab c-tab"
|
||||
v-for="(tab,index) in tabsList"
|
||||
:key="index"
|
||||
:class="[
|
||||
@ -26,7 +26,8 @@
|
||||
v-for="(tab, index) in tabsList"
|
||||
:key="index"
|
||||
:class="{'invisible': !isCurrent(tab)}">
|
||||
<div class="c-tabs-view__object-name l-browse-bar__object-name--w"
|
||||
<div v-if="currentTab"
|
||||
class="c-tabs-view__object-name l-browse-bar__object-name--w"
|
||||
:class="currentTab.type.definition.cssClass">
|
||||
<div class="l-browse-bar__object-name">
|
||||
{{currentTab.domainObject.name}}
|
||||
@ -53,11 +54,16 @@
|
||||
}
|
||||
|
||||
&__tabs-holder {
|
||||
@include userSelectNone();
|
||||
flex: 0 0 auto;
|
||||
min-height: $h;
|
||||
}
|
||||
|
||||
&__tab {
|
||||
&:before {
|
||||
margin-right: $interiorMarginSm;
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
&__object-holder {
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
@ -76,6 +82,7 @@
|
||||
}
|
||||
|
||||
&__empty-message {
|
||||
background: rgba($colorBodyFg, 0.1);
|
||||
color: rgba($colorBodyFg, 0.7);
|
||||
font-style: italic;
|
||||
text-align: center;
|
||||
@ -140,6 +147,13 @@ export default {
|
||||
this.showTab(this.tabsList[this.tabsList.length - 1]);
|
||||
}
|
||||
},
|
||||
onReorder(reorderPlan) {
|
||||
let oldTabs = this.tabsList.slice();
|
||||
|
||||
reorderPlan.forEach(reorderEvent => {
|
||||
this.$set(this.tabsList, reorderEvent.newIndex, oldTabs[reorderEvent.oldIndex]);
|
||||
});
|
||||
},
|
||||
onDrop(e) {
|
||||
this.setCurrentTab = true;
|
||||
},
|
||||
@ -166,6 +180,7 @@ export default {
|
||||
if (this.composition) {
|
||||
this.composition.on('add', this.addItem);
|
||||
this.composition.on('remove', this.removeItem);
|
||||
this.composition.on('reorder', this.onReorder);
|
||||
this.composition.load();
|
||||
}
|
||||
|
||||
@ -182,6 +197,7 @@ export default {
|
||||
destroyed() {
|
||||
this.composition.off('add', this.addItem);
|
||||
this.composition.off('remove', this.removeItem);
|
||||
this.composition.off('reorder', this.onReorder);
|
||||
|
||||
document.removeEventListener('dragstart', this.dragstart);
|
||||
document.removeEventListener('dragend', this.dragend);
|
||||
|
@ -59,6 +59,7 @@ define([
|
||||
this.filterObserver = undefined;
|
||||
|
||||
this.createTableRowCollections();
|
||||
|
||||
openmct.time.on('bounds', this.refreshData);
|
||||
openmct.time.on('timeSystem', this.refreshData);
|
||||
}
|
||||
@ -74,13 +75,17 @@ define([
|
||||
|
||||
createTableRowCollections() {
|
||||
this.boundedRows = new BoundedTableRowCollection(this.openmct);
|
||||
|
||||
//By default, sort by current time system, ascending.
|
||||
this.filteredRows = new FilteredTableRowCollection(this.boundedRows);
|
||||
this.filteredRows.sortBy({
|
||||
|
||||
//Fetch any persisted default sort
|
||||
let sortOptions = this.configuration.getConfiguration().sortOptions;
|
||||
|
||||
//If no persisted sort order, default to sorting by time system, ascending.
|
||||
sortOptions = sortOptions || {
|
||||
key: this.openmct.time.timeSystem().key,
|
||||
direction: 'asc'
|
||||
});
|
||||
};
|
||||
this.filteredRows.sortBy(sortOptions);
|
||||
}
|
||||
|
||||
loadComposition() {
|
||||
@ -210,6 +215,16 @@ define([
|
||||
delete this.subscriptions[keyString];
|
||||
}
|
||||
|
||||
sortBy(sortOptions) {
|
||||
this.filteredRows.sortBy(sortOptions);
|
||||
|
||||
if (this.openmct.editor.isEditing()) {
|
||||
let configuration = this.configuration.getConfiguration();
|
||||
configuration.sortOptions = sortOptions;
|
||||
this.configuration.updateConfiguration(configuration);
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.boundedRows.destroy();
|
||||
this.filteredRows.destroy();
|
||||
|
@ -32,12 +32,20 @@ define([
|
||||
Vue
|
||||
) {
|
||||
function TelemetryTableViewProvider(openmct) {
|
||||
function hasTelemetry(domainObject) {
|
||||
if (!domainObject.hasOwnProperty('telemetry')) {
|
||||
return false;
|
||||
}
|
||||
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||
return metadata.values().length > 0;
|
||||
}
|
||||
return {
|
||||
key: 'table',
|
||||
name: 'Telemetry Table',
|
||||
cssClass: 'icon-tabular-realtime',
|
||||
canView(domainObject) {
|
||||
return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
|
||||
return domainObject.type === 'table' ||
|
||||
hasTelemetry(domainObject)
|
||||
},
|
||||
canEdit(domainObject) {
|
||||
return domainObject.type === 'table';
|
||||
|
@ -409,7 +409,7 @@ export default {
|
||||
direction: 'asc'
|
||||
}
|
||||
}
|
||||
this.table.filteredRows.sortBy(this.sortOptions);
|
||||
this.table.sortBy(this.sortOptions);
|
||||
},
|
||||
scroll() {
|
||||
if (!this.processingScroll) {
|
||||
@ -432,9 +432,9 @@ export default {
|
||||
shouldSnapToBottom() {
|
||||
return this.scrollable.scrollTop >= (this.scrollable.scrollHeight - this.scrollable.offsetHeight - AUTO_SCROLL_TRIGGER_HEIGHT);
|
||||
},
|
||||
scrollToBottom() {
|
||||
scrollToBottom: _.throttle(function() {
|
||||
this.scrollable.scrollTop = this.scrollable.scrollHeight;
|
||||
},
|
||||
}, 100),
|
||||
synchronizeScrollX() {
|
||||
this.headersHolderEl.scrollLeft = this.scrollable.scrollLeft;
|
||||
},
|
||||
|
@ -23,73 +23,76 @@
|
||||
<div class="c-conductor"
|
||||
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']">
|
||||
<form class="u-contents" ref="conductorForm" @submit.prevent="updateTimeFromConductor">
|
||||
<button class="c-input--submit" type="submit" ref="submitButton"></button>
|
||||
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
||||
<div class="c-conductor__time-bounds">
|
||||
<button class="c-input--submit" type="submit" ref="submitButton"></button>
|
||||
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
||||
v-if="isFixed">
|
||||
<!-- Fixed start -->
|
||||
<div class="c-conductor__start-fixed__label">Start</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
ref="startDate"
|
||||
v-model="formattedBounds.start"
|
||||
@change="validateAllBounds(); submitForm()" />
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
:default-date-time="formattedBounds.start"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="startDateSelected"></date-picker>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT start -->
|
||||
<div class="c-direction-indicator icon-minus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text" autocorrect="off"
|
||||
ref="startOffset"
|
||||
spellcheck="false"
|
||||
v-model="offsets.start"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-fixed">
|
||||
<!-- Fixed end and RT 'last update' display -->
|
||||
<div class="c-conductor__end-fixed__label">
|
||||
{{ isFixed ? 'End' : 'Updated' }}
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
||||
v-if="isFixed">
|
||||
<!-- Fixed start -->
|
||||
<div class="c-conductor__start-fixed__label">Start</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
ref="startDate"
|
||||
v-model="formattedBounds.start"
|
||||
@change="validateAllBounds(); submitForm()" />
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
:default-date-time="formattedBounds.start"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="startDateSelected"></date-picker>
|
||||
</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="formattedBounds.end"
|
||||
:disabled="!isFixed"
|
||||
ref="endDate"
|
||||
@change="validateAllBounds(); submitForm()">
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
class="c-ctrl-wrapper--menus-left"
|
||||
:default-date-time="formattedBounds.end"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="endDateSelected"></date-picker>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT end -->
|
||||
<div class="c-direction-indicator icon-plus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
ref="endOffset"
|
||||
v-model="offsets.end"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
</div>
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT start -->
|
||||
<div class="c-direction-indicator icon-minus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text" autocorrect="off"
|
||||
ref="startOffset"
|
||||
spellcheck="false"
|
||||
v-model="offsets.start"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
</div>
|
||||
|
||||
<conductor-axis
|
||||
class="c-conductor__ticks"
|
||||
:bounds="rawBounds"
|
||||
@panAxis="setViewFromBounds"></conductor-axis>
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-fixed">
|
||||
<!-- Fixed end and RT 'last update' display -->
|
||||
<div class="c-conductor__end-fixed__label">
|
||||
{{ isFixed ? 'End' : 'Updated' }}
|
||||
</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="formattedBounds.end"
|
||||
:disabled="!isFixed"
|
||||
ref="endDate"
|
||||
@change="validateAllBounds(); submitForm()">
|
||||
<date-picker
|
||||
v-if="isFixed && isUTCBased"
|
||||
class="c-ctrl-wrapper--menus-left"
|
||||
:default-date-time="formattedBounds.end"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="endDateSelected"></date-picker>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT end -->
|
||||
<div class="c-direction-indicator icon-plus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
ref="endOffset"
|
||||
v-model="offsets.end"
|
||||
@change="validateAllOffsets(); submitForm()">
|
||||
</div>
|
||||
|
||||
<conductor-axis
|
||||
class="c-conductor__ticks"
|
||||
:bounds="rawBounds"
|
||||
@panAxis="setViewFromBounds"></conductor-axis>
|
||||
|
||||
</div>
|
||||
<div class="c-conductor__controls">
|
||||
<!-- Mode, time system menu buttons and duration slider -->
|
||||
<ConductorMode class="c-conductor__mode-select"></ConductorMode>
|
||||
@ -113,17 +116,17 @@
|
||||
|
||||
/*********************************************** CONDUCTOR LAYOUT */
|
||||
.c-conductor {
|
||||
display: grid;
|
||||
grid-column-gap: $interiorMargin;
|
||||
grid-row-gap: $interiorMargin;
|
||||
align-items: center;
|
||||
&__time-bounds {
|
||||
display: grid;
|
||||
grid-column-gap: $interiorMargin;
|
||||
grid-row-gap: $interiorMargin;
|
||||
align-items: center;
|
||||
|
||||
// Default: fixed mode, desktop
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-columns: 20px auto 1fr auto;
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start tc-ticks tc-end"
|
||||
"tc-controls tc-controls tc-controls tc-controls";
|
||||
// Default: fixed mode, desktop
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: 20px auto 1fr auto;
|
||||
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-end";
|
||||
}
|
||||
|
||||
&__mode-icon {
|
||||
grid-area: tc-mode-icon;
|
||||
@ -163,10 +166,10 @@
|
||||
}
|
||||
|
||||
&.is-realtime-mode {
|
||||
grid-template-columns: 20px auto 1fr auto auto;
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start tc-ticks tc-updated tc-end"
|
||||
"tc-controls tc-controls tc-controls tc-controls tc-controls";
|
||||
.c-conductor__time-bounds {
|
||||
grid-template-columns: 20px auto 1fr auto auto;
|
||||
grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-updated tc-end";
|
||||
}
|
||||
|
||||
.c-conductor__end-fixed {
|
||||
grid-area: tc-updated;
|
||||
@ -174,9 +177,15 @@
|
||||
}
|
||||
|
||||
body.phone.portrait & {
|
||||
grid-row-gap: $interiorMargin;
|
||||
grid-template-rows: auto auto auto;
|
||||
grid-template-columns: 20px auto auto;
|
||||
.c-conductor__time-bounds {
|
||||
grid-row-gap: $interiorMargin;
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: 20px auto auto;
|
||||
}
|
||||
|
||||
.c-conductor__controls {
|
||||
padding-left: 25px; // Line up visually with other controls
|
||||
}
|
||||
|
||||
&__mode-icon {
|
||||
grid-row: 1;
|
||||
@ -200,17 +209,19 @@
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
grid-template-areas:
|
||||
.c-conductor__time-bounds {
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start tc-start"
|
||||
"tc-mode-icon tc-end tc-end"
|
||||
"tc-mode-icon tc-controls tc-controls";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.is-realtime-mode {
|
||||
grid-template-areas:
|
||||
.c-conductor__time-bounds {
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start tc-updated"
|
||||
"tc-mode-icon tc-end tc-end"
|
||||
"tc-mode-icon tc-controls tc-controls";
|
||||
"tc-mode-icon tc-end tc-end";
|
||||
}
|
||||
|
||||
.c-conductor__end-fixed {
|
||||
justify-content: flex-end;
|
||||
|
@ -83,6 +83,9 @@ $uiColor: #00b2ff; // Resize bars, splitter bars, etc.
|
||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||
$colorA: #ccc;
|
||||
$colorAHov: #fff;
|
||||
$filterHov: brightness(1.3); // Tree, location items
|
||||
$colorSelectedBg: pushBack($colorKey, 10%);
|
||||
$colorSelectedFg: pullForward($colorBodyFg, 20%);
|
||||
|
||||
// Layout
|
||||
$shellMainPad: 4px 0;
|
||||
@ -98,6 +101,20 @@ $colorStatusAlertFilter: invert(78%) sepia(26%) saturate(1160%) hue-rotate(324de
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusErrorFilter: invert(10%) sepia(96%) saturate(4360%) hue-rotate(351deg) brightness(111%) contrast(115%);
|
||||
$colorStatusBtnBg: #666; // Where is this used?
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@ -173,6 +190,10 @@ $colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||
$colorBtnCautionBg: #f16f6f;
|
||||
$colorBtnCautionBgHov: #f1504e;
|
||||
$colorBtnCautionFg: $colorBtnFg;
|
||||
$colorBtnActiveBg: $colorOk;
|
||||
$colorBtnActiveFg: $colorOkFg;
|
||||
$colorBtnSelectedBg: $colorSelectedBg;
|
||||
$colorBtnSelectedFg: $colorSelectedFg;
|
||||
$colorClickIconButton: $colorKey;
|
||||
$colorClickIconButtonBgHov: rgba($colorKey, 0.6);
|
||||
$colorClickIconButtonFgHov: $colorKeyHov;
|
||||
@ -265,26 +286,9 @@ $colorLimitRedBg: #940000;
|
||||
$colorLimitRedFg: #ffa489;
|
||||
$colorLimitRedIc: #ff4222;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: #dddddd;
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorThumbsBubbleFg: pullForward($colorBodyFg, 10%);
|
||||
$colorThumbsBubbleBg: pullForward($colorBodyBg, 10%);
|
||||
|
||||
@ -306,6 +310,9 @@ $colorTabHeaderFg: $colorBodyFg;
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
|
||||
$colorSummaryBg: #2c2c2c;
|
||||
$colorSummaryFg: rgba($colorBodyFg, 0.7);
|
||||
$colorSummaryFgEm: $colorBodyFg;
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -324,7 +331,7 @@ $colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
|
||||
$colorItemTreeIcon: $colorKey; // Used
|
||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||
$colorItemTreeFg: $colorBodyFg;
|
||||
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||
$colorItemTreeSelectedBg: $colorSelectedBg;
|
||||
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||
|
@ -87,6 +87,9 @@ $uiColor: #00b2ff; // Resize bars, splitter bars, etc.
|
||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||
$colorA: #ccc;
|
||||
$colorAHov: #fff;
|
||||
$filterHov: brightness(1.3); // Tree, location items
|
||||
$colorSelectedBg: pushBack($colorKey, 10%);
|
||||
$colorSelectedFg: pullForward($colorBodyFg, 20%);
|
||||
|
||||
// Layout
|
||||
$shellMainPad: 4px 0;
|
||||
@ -102,6 +105,20 @@ $colorStatusAlertFilter: invert(78%) sepia(26%) saturate(1160%) hue-rotate(324de
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusErrorFilter: invert(10%) sepia(96%) saturate(4360%) hue-rotate(351deg) brightness(111%) contrast(115%);
|
||||
$colorStatusBtnBg: #666; // Where is this used?
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@ -177,6 +194,10 @@ $colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||
$colorBtnCautionBg: #f16f6f;
|
||||
$colorBtnCautionBgHov: #f1504e;
|
||||
$colorBtnCautionFg: $colorBtnFg;
|
||||
$colorBtnActiveBg: $colorOk;
|
||||
$colorBtnActiveFg: $colorOkFg;
|
||||
$colorBtnSelectedBg: $colorSelectedBg;
|
||||
$colorBtnSelectedFg: $colorSelectedFg;
|
||||
$colorClickIconButton: $colorKey;
|
||||
$colorClickIconButtonBgHov: rgba($colorKey, 0.6);
|
||||
$colorClickIconButtonFgHov: $colorKeyHov;
|
||||
@ -269,26 +290,9 @@ $colorLimitRedBg: #940000;
|
||||
$colorLimitRedFg: #ffa489;
|
||||
$colorLimitRedIc: #ff4222;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: #dddddd;
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorInfoBubbleFg: #666;
|
||||
$colorThumbsBubbleFg: pullForward($colorBodyFg, 10%);
|
||||
$colorThumbsBubbleBg: pullForward($colorBodyBg, 10%);
|
||||
|
||||
@ -310,6 +314,9 @@ $colorTabHeaderFg: $colorBodyFg;
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
|
||||
$colorSummaryBg: #2c2c2c;
|
||||
$colorSummaryFg: rgba($colorBodyFg, 0.7);
|
||||
$colorSummaryFgEm: $colorBodyFg;
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -328,7 +335,7 @@ $colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
|
||||
$colorItemTreeIcon: $colorKey; // Used
|
||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||
$colorItemTreeFg: $colorBodyFg;
|
||||
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||
$colorItemTreeSelectedBg: $colorSelectedBg;
|
||||
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||
@ -375,7 +382,7 @@ $colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
||||
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
||||
|
||||
// About Screen
|
||||
$colorAboutLink: $colorKeySubtle;
|
||||
$colorAboutLink: #9bb5ff;
|
||||
|
||||
// Loading
|
||||
$colorLoadingFg: #776ba2;
|
||||
|
@ -83,6 +83,9 @@ $uiColor: #289fec; // Resize bars, splitter bars, etc.
|
||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||
$colorA: #999;
|
||||
$colorAHov: $colorKey;
|
||||
$filterHov: brightness(1.3); // Tree, location items
|
||||
$colorSelectedBg: pushBack($colorKey, 40%);
|
||||
$colorSelectedFg: pullForward($colorBodyFg, 10%);
|
||||
|
||||
// Layout
|
||||
$shellMainPad: 4px 0;
|
||||
@ -98,6 +101,20 @@ $colorStatusAlertFilter: invert(89%) sepia(26%) saturate(5035%) hue-rotate(316de
|
||||
$colorStatusError: #da0004;
|
||||
$colorStatusErrorFilter: invert(8%) sepia(96%) saturate(4511%) hue-rotate(352deg) brightness(136%) contrast(114%);
|
||||
$colorStatusBtnBg: #666; // Where is this used?
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@ -173,6 +190,10 @@ $colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||
$colorBtnCautionBg: #f16f6f;
|
||||
$colorBtnCautionBgHov: #f1504e;
|
||||
$colorBtnCautionFg: $colorBtnFg;
|
||||
$colorBtnActiveBg: $colorOk;
|
||||
$colorBtnActiveFg: $colorOkFg;
|
||||
$colorBtnSelectedBg: $colorBtnMajorBg;
|
||||
$colorBtnSelectedFg: $colorBtnMajorFg;
|
||||
$colorClickIconButton: $colorKey;
|
||||
$colorClickIconButtonBgHov: rgba($colorKey, 0.2);
|
||||
$colorClickIconButtonFgHov: $colorKeyHov;
|
||||
@ -265,22 +286,6 @@ $colorLimitRedBg: #ff0000;
|
||||
$colorLimitRedFg: #fff;
|
||||
$colorLimitRedIc: #ffa99a;
|
||||
|
||||
// Status
|
||||
$colorAlert: #ff3c00;
|
||||
$colorAlertFg: #fff;
|
||||
$colorWarningHi: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
$colorDiagnosticFg: #39461A;
|
||||
$colorCommand: #3693bd;
|
||||
$colorCommandFg: #fff;
|
||||
$colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
|
||||
// Bubble colors
|
||||
$colorInfoBubbleBg: $colorMenuBg;
|
||||
$colorInfoBubbleFg: #666;
|
||||
@ -305,6 +310,9 @@ $colorTabHeaderFg: pullForward($colorBodyFg, 20%);
|
||||
$colorTabHeaderBorder: $colorBodyBg;
|
||||
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||
$colorTabGroupHeaderFg: pullForward($colorTabGroupHeaderBg, 40%);
|
||||
$colorSummaryBg: #999;
|
||||
$colorSummaryFg: rgba($colorBodyBg, 0.7);
|
||||
$colorSummaryFgEm: white;
|
||||
|
||||
// Plot
|
||||
$colorPlotBg: rgba(black, 0.05);
|
||||
@ -323,8 +331,8 @@ $colorItemTreeHoverFg: pullForward($colorBodyFg, 10%);
|
||||
$colorItemTreeIcon: $colorKey; // Used
|
||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||
$colorItemTreeFg: $colorBodyFg;
|
||||
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||
$colorItemTreeSelectedFg: $colorBodyBg;
|
||||
$colorItemTreeSelectedBg: $colorSelectedBg;
|
||||
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||
$colorItemTreeEditingFg: $editUIColor;
|
||||
@ -347,6 +355,7 @@ $scrollbarThumbColorMenuHov: darken($scrollbarThumbColorMenu, 2%);
|
||||
|
||||
// Splitter
|
||||
$splitterHandleD: 2px;
|
||||
$splitterD: $splitterHandleD;
|
||||
$splitterHandleHitMargin: 4px;
|
||||
$colorSplitterBaseBg: $colorBodyBg;
|
||||
$colorSplitterBg: pullForward($colorSplitterBaseBg, 20%);
|
||||
|
@ -80,7 +80,7 @@ $formLabelW: 30%;
|
||||
$waitSpinnerD: 32px;
|
||||
$waitSpinnerTreeD: 20px;
|
||||
$waitSpinnerBorderW: 5px;
|
||||
$waitSpinnerTreeBorderW: 4px;
|
||||
$waitSpinnerTreeBorderW: 3px;
|
||||
/*************** Messages */
|
||||
$messageIconD: 80px;
|
||||
$messageListIconD: 32px;
|
||||
|
@ -48,10 +48,16 @@ button {
|
||||
height: $d; width: $d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-compact-button {
|
||||
@include cCompactButtons($bg: $colorBtnBg, $fg: $colorBtnFg, $bgHov: $colorBtnBgHov);
|
||||
&.is-active {
|
||||
background: $colorBtnActiveBg;
|
||||
color: $colorBtnActiveFg;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
background: $colorBtnSelectedBg;
|
||||
color: $colorBtnSelectedFg;
|
||||
}
|
||||
}
|
||||
|
||||
/********* Icon Buttons */
|
||||
@ -143,7 +149,7 @@ button {
|
||||
font-family: symbolsfont;
|
||||
font-size: 1rem * $s;
|
||||
transform-origin: center;
|
||||
transition: transform 100ms ease-in-out;
|
||||
transition: $transOut;
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,6 +276,63 @@ select {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** TABS */
|
||||
.c-tabs {
|
||||
// Single horizontal strip of tabs, with a bottom divider line
|
||||
@include userSelectNone();
|
||||
display: flex;
|
||||
flex: 0 0 auto;
|
||||
flex-wrap: wrap;
|
||||
position: relative; // Required in case this is applied to a <ul>
|
||||
|
||||
&:before {
|
||||
// Separator line at bottom of tabs
|
||||
content: '';
|
||||
display: block;
|
||||
height: 1px;
|
||||
width: 100%;
|
||||
background: $colorBtnReverseBg;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.c-tab {
|
||||
// Used in Tab View, generic tabs
|
||||
background: $colorBtnBg;
|
||||
color: $colorBtnFg;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex: 1 1 auto;
|
||||
margin: 1px 1px 0 0;
|
||||
padding: $interiorMargin $interiorMarginLg;
|
||||
white-space: nowrap;
|
||||
|
||||
--notchSize: 7px;
|
||||
|
||||
clip-path:
|
||||
polygon(
|
||||
0% 0%,
|
||||
calc(100% - var(--notchSize)) 0%,
|
||||
100% var(--notchSize),
|
||||
100% calc(100% - var(--notchSize)),
|
||||
100% 100%,
|
||||
0% 100%
|
||||
);
|
||||
|
||||
@include hover() {
|
||||
background: $colorBtnBgHov;
|
||||
}
|
||||
|
||||
&.is-current {
|
||||
background: $colorBtnReverseBg;
|
||||
color: $colorBtnReverseFg;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
||||
.c-hyperlink {
|
||||
&--link {
|
||||
@ -658,7 +721,6 @@ input[type="range"] {
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************** LOCAL CONTROLS */
|
||||
.h-local-controls {
|
||||
// Holder for local controls
|
||||
&--horz {
|
||||
|
@ -101,7 +101,6 @@
|
||||
min-width: 120px;
|
||||
order: 1;
|
||||
position: relative;
|
||||
white-space: nowrap;
|
||||
width: $formLabelW;
|
||||
}
|
||||
|
||||
@ -121,26 +120,35 @@
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.select {
|
||||
|
||||
.l-input-lg { // LEGACY FORM SUPPORT
|
||||
input[type=text],
|
||||
input[type=search],
|
||||
input[type=number] {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
select {
|
||||
margin-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.hint, .field-hints { color: $colorFieldHint; }
|
||||
}
|
||||
}
|
||||
|
||||
.selector-list {
|
||||
// Used in create overlay to display tree view
|
||||
@include nice-input();
|
||||
padding: $interiorMargin;
|
||||
position: relative;
|
||||
min-height: 150px;
|
||||
height: 100%;
|
||||
>.wrapper {
|
||||
$p: $interiorMargin;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
.selector-list {
|
||||
// Displays tree view in dialogs
|
||||
@include nice-input();
|
||||
padding: $interiorMargin;
|
||||
position: relative;
|
||||
min-height: 0; // Chrome 73 overflow bug fix
|
||||
height: 100%;
|
||||
>.wrapper {
|
||||
$p: $interiorMargin;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,8 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************* RESETS */
|
||||
/******************************************************** RESETS */
|
||||
*,
|
||||
:before,
|
||||
:after {
|
||||
@ -31,7 +30,7 @@ div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/******************************* UTILITIES */
|
||||
/******************************************************** UTILITIES */
|
||||
.u-contents {
|
||||
display: contents;
|
||||
}
|
||||
@ -45,7 +44,7 @@ div {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* BROWSER ELEMENTS */
|
||||
/******************************************************** BROWSER ELEMENTS */
|
||||
body.desktop {
|
||||
::-webkit-scrollbar {
|
||||
box-sizing: border-box;
|
||||
@ -75,7 +74,7 @@ body.desktop {
|
||||
}
|
||||
}
|
||||
|
||||
/************************** HTML ENTITIES */
|
||||
/******************************************************** HTML ENTITIES */
|
||||
a {
|
||||
color: $colorA;
|
||||
cursor: pointer;
|
||||
@ -167,7 +166,6 @@ body.desktop .has-local-controls {
|
||||
|
||||
/******************************************************** SELECTION AND EDITING */
|
||||
// Provides supporting styles for Display Layouts and augmented legacy Fixed Position view
|
||||
|
||||
.c-grid,
|
||||
.c-grid__x,
|
||||
.c-grid__y {
|
||||
@ -204,169 +202,88 @@ body.desktop .has-local-controls {
|
||||
}
|
||||
}
|
||||
|
||||
/************************** LEGACY */
|
||||
|
||||
mct-container {
|
||||
/******************************************************** STATES */
|
||||
@mixin spinner($b: 5px, $c: $colorKey) {
|
||||
animation-name: rotation-centered;
|
||||
animation-duration: 0.5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
border-color: rgba($c, 0.25);
|
||||
border-top-color: rgba($c, 1.0);
|
||||
border-style: solid;
|
||||
border-width: $b;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.abs {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
left: 50%; top: 50%;
|
||||
transform-origin: center;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.code {
|
||||
font-family: "Lucida Console", monospace;
|
||||
font-size: 0.7em;
|
||||
line-height: 150%;
|
||||
white-space: pre;
|
||||
.wait-spinner {
|
||||
@include spinner($waitSpinnerBorderW, $colorKey);
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
&.inline {
|
||||
display: inline-block !important;
|
||||
margin-right: $interiorMargin;
|
||||
position: relative !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.codehilite {
|
||||
@extend .code;
|
||||
background-color: rgba($colorBodyFg, 0.1);
|
||||
padding: 1em;
|
||||
.loading {
|
||||
// Can be applied to any block element with height and width
|
||||
pointer-events: none;
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
}
|
||||
&:before {
|
||||
@include spinner($waitSpinnerBorderW, $colorLoadingFg);
|
||||
height: $waitSpinnerD; width: $waitSpinnerD;
|
||||
z-index: 10;
|
||||
}
|
||||
&:after {
|
||||
@include abs();
|
||||
background: $colorLoadingBg;
|
||||
display: block;
|
||||
z-index: 9;
|
||||
}
|
||||
&.c-tree__item {
|
||||
$d: $waitSpinnerTreeD;
|
||||
$spinnerL: 19px + $d/2;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: $spinnerL + $d/2 + $interiorMargin;
|
||||
background: $colorLoadingBg;
|
||||
min-height: 5px + $d;
|
||||
|
||||
.c-tree__item__label {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
&:before {
|
||||
height: $d;
|
||||
width: $d;
|
||||
border-width: 4px;
|
||||
left: $spinnerL;
|
||||
}
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.c-loading--overlay {
|
||||
@include abs();
|
||||
}
|
||||
}
|
||||
|
||||
*[disabled],
|
||||
.disabled,
|
||||
a.disabled {
|
||||
.disabled {
|
||||
opacity: $controlDisabledOpacity;
|
||||
pointer-events: none !important;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
.s-status-missing {
|
||||
// Labels. Expects .s-status-missing to be applied to mct-representation that contains
|
||||
.t-object-label .t-item-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
|
||||
// Item, grid item. Expects .s-status-missing to be applied to mct-representation that contains .item.grid-item
|
||||
.item .t-item-icon-glyph:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
|
||||
// Object header. Expects .s-status-missing to be applied to mct-representation.object-header
|
||||
&.object-header {
|
||||
.type-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
}
|
||||
|
||||
// Tree item. Expects .s-status-missing to be applied to .tree-item,
|
||||
// and mct-representation.search-item
|
||||
&.tree-item,
|
||||
&.search-item {
|
||||
> .rep-object-label .t-item-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-selection {
|
||||
// aka selection = "None". Used in palettes and their menu buttons.
|
||||
$c: red;
|
||||
$s: 48%;
|
||||
$e: 52%;
|
||||
background-image: linear-gradient(-45deg,
|
||||
transparent $s - 5%,
|
||||
$c $s,
|
||||
$c $e,
|
||||
transparent $e + 5%
|
||||
);
|
||||
box-shadow:inset rgba(black, 0.3) 0 0 0 1px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.scrolling,
|
||||
.scroll {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.vscroll {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
&.scroll-pad {
|
||||
padding-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.vscroll--persist {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.slidable {
|
||||
cursor: move; // Fallback
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
&.horz {
|
||||
cursor: col-resize;
|
||||
}
|
||||
&.vert {
|
||||
cursor: row-resize;
|
||||
}
|
||||
}
|
||||
|
||||
.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ds {
|
||||
box-shadow: rgba(#000, 0.7) 0 4px 10px 2px;
|
||||
}
|
||||
|
||||
.capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.hide,
|
||||
.hidden,
|
||||
.t-main-view .hide-in-t-main-view {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.hide-nice {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0 !important;
|
||||
transform: scale(0);
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.sep {
|
||||
color: rgba(#fff, 0.2);
|
||||
}
|
||||
|
||||
.comma-list span {
|
||||
&:not(:first-child) {
|
||||
&:before {
|
||||
content: ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +461,7 @@ body.mobile.phone {
|
||||
width: $ruleLabelW;
|
||||
}
|
||||
|
||||
.t-message-widget-no-data {
|
||||
.js-summary-widget__message {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -508,7 +508,7 @@ body.mobile.phone {
|
||||
&.expanded-widget-rules {
|
||||
.widget-rules-wrapper {
|
||||
min-height: 50px;
|
||||
height: auto;
|
||||
height: 100%; // Fix for Chrome 73 scrolling bug
|
||||
opacity: 1;
|
||||
pointer-events: inherit;
|
||||
}
|
||||
@ -520,7 +520,7 @@ body.mobile.phone {
|
||||
opacity: 0.3;
|
||||
pointer-events: none;
|
||||
}
|
||||
.t-message-widget-no-data {
|
||||
.js-summary-widget__message {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
@ -804,7 +804,9 @@ mct-indicators mct-include {
|
||||
}
|
||||
|
||||
.label {
|
||||
// Hover bubbles that appear when hovering on an Indicator
|
||||
display: inline-block;
|
||||
|
||||
a,
|
||||
button,
|
||||
s-button,
|
||||
@ -851,8 +853,6 @@ mct-indicators mct-include {
|
||||
}
|
||||
|
||||
&:not(.no-collapse) {
|
||||
z-index: 0;
|
||||
|
||||
&:before {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
@ -870,6 +870,8 @@ mct-indicators mct-include {
|
||||
transform-origin: 10px 100%;
|
||||
transform: scale(0.0);
|
||||
white-space: nowrap;
|
||||
z-index: 50;
|
||||
|
||||
&:before {
|
||||
// Infobubble-style arrow element
|
||||
content: '';
|
||||
@ -880,9 +882,9 @@ mct-indicators mct-include {
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@include hover() {
|
||||
background: $bg;
|
||||
z-index: 1;
|
||||
|
||||
.label {
|
||||
opacity: 1;
|
||||
transform: scale(1.0);
|
||||
@ -1175,79 +1177,6 @@ body.desktop {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************* WAIT SPINNERS */
|
||||
@mixin spinner($b: 5px, $c: $colorKey) {
|
||||
animation-name: rotation-centered;
|
||||
animation-duration: 0.5s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
border-color: rgba($c, 0.25);
|
||||
border-top-color: rgba($c, 1.0);
|
||||
border-style: solid;
|
||||
border-width: $b;
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%; top: 50%;
|
||||
transform-origin: center;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wait-spinner {
|
||||
@include spinner($waitSpinnerBorderW, $colorKey);
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
&.inline {
|
||||
display: inline-block !important;
|
||||
margin-right: $interiorMargin;
|
||||
position: relative !important;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
// Can be applied to any block element with height and width
|
||||
pointer-events: none;
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
}
|
||||
&:before {
|
||||
@include spinner($waitSpinnerBorderW, $colorLoadingFg);
|
||||
height: $waitSpinnerD; width: $waitSpinnerD;
|
||||
z-index: 10;
|
||||
}
|
||||
&:after {
|
||||
@include abs();
|
||||
background: $colorLoadingBg;
|
||||
display: block;
|
||||
z-index: 9;
|
||||
}
|
||||
&.tree-item.t-wait-node {
|
||||
$d: $waitSpinnerTreeD;
|
||||
$spinnerL: $interiorMargin + 19px + $d/2;
|
||||
padding-left: $spinnerL + $d/2 + $interiorMargin;
|
||||
.t-title-label {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
}
|
||||
&:before {
|
||||
height: $d;
|
||||
width: $d;
|
||||
border-width: 4px;
|
||||
left: $spinnerL;
|
||||
}
|
||||
&:after {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&.c-loading--overlay {
|
||||
@include abs();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************* FLEX STYLES */
|
||||
.l-flex-row,
|
||||
.l-flex-col {
|
||||
@ -1314,7 +1243,7 @@ body.desktop {
|
||||
.grid-properties {
|
||||
display: grid;
|
||||
grid-row-gap: 0;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
grid-template-columns: 1fr 2fr;
|
||||
}
|
||||
|
||||
.grid-span-all,
|
||||
@ -1512,6 +1441,10 @@ body.desktop {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
mct-container {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
.outer-holder {
|
||||
background: $colorMenuBg;
|
||||
@ -1577,3 +1510,157 @@ body.desktop {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.abs {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.code {
|
||||
font-family: "Lucida Console", monospace;
|
||||
font-size: 0.7em;
|
||||
line-height: 150%;
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.codehilite {
|
||||
@extend .code;
|
||||
background-color: rgba($colorBodyFg, 0.1);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.s-status-missing {
|
||||
// Labels. Expects .s-status-missing to be applied to mct-representation that contains
|
||||
.t-object-label .t-item-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
|
||||
// Item, grid item. Expects .s-status-missing to be applied to mct-representation that contains .item.grid-item
|
||||
.item .t-item-icon-glyph:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
|
||||
// Object header. Expects .s-status-missing to be applied to mct-representation.object-header
|
||||
&.object-header {
|
||||
.type-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
}
|
||||
|
||||
// Tree item. Expects .s-status-missing to be applied to .tree-item,
|
||||
// and mct-representation.search-item
|
||||
&.tree-item,
|
||||
&.search-item {
|
||||
> .rep-object-label .t-item-icon:before {
|
||||
content: $glyph-icon-object-unknown;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.align-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.no-selection {
|
||||
// aka selection = "None". Used in palettes and their menu buttons.
|
||||
$c: red;
|
||||
$s: 48%;
|
||||
$e: 52%;
|
||||
background-image: linear-gradient(-45deg,
|
||||
transparent $s - 5%,
|
||||
$c $s,
|
||||
$c $e,
|
||||
transparent $e + 5%
|
||||
);
|
||||
box-shadow:inset rgba(black, 0.3) 0 0 0 1px;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.scrolling,
|
||||
.scroll {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.vscroll {
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
&.scroll-pad {
|
||||
padding-right: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.vscroll--persist {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.slidable {
|
||||
cursor: move; // Fallback
|
||||
cursor: grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: -webkit-grab;
|
||||
&.horz {
|
||||
cursor: col-resize;
|
||||
}
|
||||
&.vert {
|
||||
cursor: row-resize;
|
||||
}
|
||||
}
|
||||
|
||||
.no-margin {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.ds {
|
||||
box-shadow: rgba(#000, 0.7) 0 4px 10px 2px;
|
||||
}
|
||||
|
||||
.capitalize {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.hide,
|
||||
.hidden,
|
||||
.t-main-view .hide-in-t-main-view {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.hide-nice {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0 !important;
|
||||
transform: scale(0);
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.sep {
|
||||
color: rgba(#fff, 0.2);
|
||||
}
|
||||
|
||||
.comma-list span {
|
||||
&:not(:first-child) {
|
||||
&:before {
|
||||
content: ', ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,50 +467,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cCompactButtons($bg, $fg, $bgHov) {
|
||||
// Used in Tab view
|
||||
// To be used in indicators popups?
|
||||
|
||||
$m: 1px;
|
||||
$btnM: $m;
|
||||
|
||||
&-holder {
|
||||
background: $colorTabsHolderBg;
|
||||
border-radius: $controlCr;
|
||||
padding: $m ($m - $btnM) ($m - $btnM) $m;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: stretch;
|
||||
|
||||
> * {
|
||||
margin: 0 $btnM $btnM 0;
|
||||
}
|
||||
}
|
||||
|
||||
background: $colorBtnBg;
|
||||
color: $colorBtnFg;
|
||||
flex: 1 1 auto;
|
||||
padding: $interiorMargin;
|
||||
|
||||
&:before {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
> * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
@include hover() {
|
||||
background: $bgHov;
|
||||
}
|
||||
|
||||
&.is-current {
|
||||
background: $colorBtnReverseBg;
|
||||
color: $colorBtnReverseFg;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
@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;
|
||||
|
@ -19,16 +19,18 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************** TABLE */
|
||||
table {
|
||||
$minW: 50px;
|
||||
width: 100%;
|
||||
|
||||
thead {
|
||||
background: $colorTabHeaderBg;
|
||||
th + th {
|
||||
border-left: 1px solid $colorTabHeaderBorder;
|
||||
th {
|
||||
background: $colorTabHeaderBg;
|
||||
|
||||
+ th {
|
||||
border-left: 1px solid $colorTabHeaderBorder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,14 +49,19 @@ table {
|
||||
td {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
a { color: $colorBtnMajorBg; }
|
||||
}
|
||||
|
||||
div.c-table {
|
||||
// When c-table is used as a wrapper element in more complex table views
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.c-table {
|
||||
// Can be used by any type of table, scrolling, LAD, etc.
|
||||
$min-w: 50px;
|
||||
|
||||
position: absolute;
|
||||
top: 0; right: 0; bottom: 0; left: 0;
|
||||
width: 100%;
|
||||
|
||||
&__control-bar,
|
||||
@ -117,4 +124,36 @@ table {
|
||||
th, td {
|
||||
width: 33%; // Needed to prevent size jumping as values dynamically update
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************************** TABLE AND SUMMARY VIEWS */
|
||||
// Displays summary values above a table.
|
||||
|
||||
.c-table-and-summary {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> * + * { margin-top: $interiorMargin; }
|
||||
|
||||
&__summary {
|
||||
display: flex;
|
||||
justify-items: stretch;
|
||||
|
||||
> * + * { margin-left: 1px; }
|
||||
}
|
||||
|
||||
&__summary-item {
|
||||
background: $colorSummaryBg;
|
||||
color: $colorSummaryFg;
|
||||
flex: 1 1 auto;
|
||||
padding: $interiorMargin $interiorMarginLg;
|
||||
|
||||
em {
|
||||
font-weight: bold;
|
||||
color: $colorSummaryFgEm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,8 @@
|
||||
// Do not include anything that renders to CSS!
|
||||
@import "constants";
|
||||
@import "constants-mobile.scss";
|
||||
@import "constants-espresso"; // TEMP
|
||||
//@import "constants-snow"; // TEMP
|
||||
//@import "constants-espresso"; // TEMP
|
||||
@import "constants-snow"; // TEMP
|
||||
//@import "constants-maelstrom";
|
||||
@import "mixins";
|
||||
@import "animations";
|
@ -5,15 +5,18 @@
|
||||
@input="applySearch"
|
||||
@clear="applySearch">
|
||||
</Search>
|
||||
<div class="c-elements-pool__elements">
|
||||
<div class="c-elements-pool__elements"
|
||||
:class="{'is-dragging': isDragging}">
|
||||
<ul class="c-tree c-elements-pool__tree" id="inspector-elements-tree"
|
||||
v-if="elements.length > 0">
|
||||
<li :key="element.identifier.key" v-for="(element, index) in elements" @drop="moveTo(index)" @dragover="allowDrop">
|
||||
<div class="c-tree__item c-elements-pool__item">
|
||||
<li :key="element.identifier.key" v-for="(element, index) in elements"
|
||||
@drop="moveTo(index)"
|
||||
@dragover="allowDrop">
|
||||
<div class="c-tree__item c-elements-pool__item"
|
||||
draggable="true"
|
||||
@dragstart="moveFrom(index)">
|
||||
<span class="c-elements-pool__grippy"
|
||||
v-if="elements.length > 1 && isEditing"
|
||||
draggable="true"
|
||||
@dragstart="moveFrom(index)">
|
||||
v-if="elements.length > 1 && isEditing">
|
||||
</span>
|
||||
<object-label :domainObject="element" :objectPath="[element, parentObject]"></object-label>
|
||||
</div>
|
||||
@ -44,18 +47,22 @@
|
||||
&__elements {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
&.is-dragging {
|
||||
li { opacity: 0.2; }
|
||||
}
|
||||
}
|
||||
|
||||
&__grippy {
|
||||
$d: 8px;
|
||||
@include grippy($c: $colorItemTreeVC, $dir: 'y');
|
||||
flex: 0 0 auto;
|
||||
margin-right: $interiorMarginSm;
|
||||
transform: translateY(-2px);
|
||||
width: $d; height: $d;
|
||||
}
|
||||
}
|
||||
|
||||
.js-last-place{
|
||||
.js-last-place {
|
||||
height: 10px;
|
||||
}
|
||||
</style>
|
||||
@ -74,7 +81,8 @@ export default {
|
||||
elements: [],
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
parentObject: undefined,
|
||||
currentSearch: ''
|
||||
currentSearch: '',
|
||||
isDragging: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -134,7 +142,7 @@ export default {
|
||||
this.applySearch(this.currentSearch);
|
||||
},
|
||||
removeElement(identifier) {
|
||||
let keyString = this.openmct.objects.makeKeyString(element.identifier);
|
||||
let keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
delete this.elementsCache[keyString];
|
||||
this.applySearch(this.currentSearch);
|
||||
},
|
||||
@ -154,12 +162,19 @@ export default {
|
||||
this.composition.reorder(this.moveFromIndex, moveToIndex);
|
||||
},
|
||||
moveFrom(index){
|
||||
this.isDragging = true;
|
||||
this.moveFromIndex = index;
|
||||
document.addEventListener('dragend', this.hideDragStyling);
|
||||
},
|
||||
hideDragStyling() {
|
||||
this.isDragging = false;
|
||||
document.removeEventListener('dragend', this.hideDragStyling);
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.openmct.editor.off('isEditing', this.setEditState);
|
||||
this.openmct.selection.off('change', this.showSelection);
|
||||
|
||||
if (this.mutationUnobserver) {
|
||||
this.mutationUnobserver();
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
min-height: 50px;
|
||||
|
||||
+ [class*="__"] {
|
||||
// Margin between elements
|
||||
margin-top: $interiorMargin;
|
||||
}
|
||||
|
||||
@ -37,9 +36,7 @@
|
||||
}
|
||||
|
||||
&__elements {
|
||||
// LEGACY TODO: Refactor when markup is updated, fix scrolling
|
||||
// so that only tree holder handles overflow
|
||||
height: 200px;
|
||||
height: 200px; // Initial height
|
||||
|
||||
.tree-item {
|
||||
.t-object-label {
|
||||
@ -64,48 +61,6 @@
|
||||
}
|
||||
|
||||
/************************************************************** LEGACY */
|
||||
// TODO: refactor when legacy properties markup can be converted
|
||||
.inspector-location {
|
||||
display: inline-block;
|
||||
|
||||
.location-item {
|
||||
$h: 1.2em;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
line-height: $h;
|
||||
position: relative;
|
||||
padding: 2px 4px;
|
||||
|
||||
.t-object-label {
|
||||
.t-item-icon {
|
||||
height: $h;
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $colorItemTreeHoverBg;
|
||||
color: $colorItemTreeHoverFg;
|
||||
.icon {
|
||||
color: $colorItemTreeIconHover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.last) .t-object-label .t-title-label:after {
|
||||
color: pushBack($colorInspectorFg, 15%);
|
||||
content: '\e904';
|
||||
display: inline-block;
|
||||
font-family: symbolsfont;
|
||||
font-size: 8px;
|
||||
font-style: normal !important;
|
||||
line-height: inherit;
|
||||
margin-left: $interiorMarginSm;
|
||||
width: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.l-inspector-part {
|
||||
display: contents;
|
||||
}
|
||||
@ -116,8 +71,8 @@
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
|
||||
.tree .grid-properties {
|
||||
margin-left: $treeItemIndent + $interiorMarginLg;
|
||||
.c-tree .grid-properties {
|
||||
margin-left: $treeItemIndent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,7 +98,6 @@
|
||||
}
|
||||
|
||||
+ .c-properties {
|
||||
// Margin between components
|
||||
margin-top: $interiorMarginLg;
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,16 @@
|
||||
<template>
|
||||
<div class="c-properties c-properties--location">
|
||||
<div class="c-properties__header" title="The location of this linked object.">Location</div>
|
||||
<div class="c-properties__header" title="The location of this linked object.">Original Location</div>
|
||||
<ul class="c-properties__section">
|
||||
<li class="c-properties__row" v-if="originalPath.length">
|
||||
<div class="c-properties__label">Original</div>
|
||||
<ul class="c-properties__value">
|
||||
<ul class="c-properties__value c-location">
|
||||
<li v-for="pathObject in orderedOriginalPath"
|
||||
class="c-location__item"
|
||||
:key="pathObject.key">
|
||||
<object-label
|
||||
:domainObject="pathObject.domainObject"
|
||||
:objectPath="pathObject.objectPath">
|
||||
</object-label>
|
||||
<span class="c-disclosure-triangle"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@ -19,8 +18,50 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-location {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
&__item {
|
||||
$m: $interiorMarginSm;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 0 $m $m 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
&:after {
|
||||
color: $colorInspectorPropName;
|
||||
content: $glyph-icon-arrow-right;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.7em;
|
||||
margin-left: $m;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.c-object-label {
|
||||
padding: 0;
|
||||
transition: $transOut;
|
||||
|
||||
&__type-icon {
|
||||
width: auto;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
transition: $transIn;
|
||||
filter: $filterHov;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import ObjectLabel from '../components/ObjectLabel.vue';
|
||||
|
||||
export default {
|
||||
@ -43,8 +84,14 @@ export default {
|
||||
this.openmct.selection.off('change', this.updateSelection);
|
||||
},
|
||||
methods: {
|
||||
setOriginalPath(path) {
|
||||
this.originalPath = path.slice(1,-1).map((domainObject, index, pathArray) => {
|
||||
setOriginalPath(path, skipSlice) {
|
||||
let originalPath = path;
|
||||
|
||||
if (!skipSlice) {
|
||||
originalPath = path.slice(1,-1);
|
||||
}
|
||||
|
||||
this.originalPath = originalPath.map((domainObject, index, pathArray) => {
|
||||
let key = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
return {
|
||||
domainObject,
|
||||
@ -53,18 +100,25 @@ export default {
|
||||
}
|
||||
});
|
||||
},
|
||||
clearData() {
|
||||
this.domainObject = {};
|
||||
this.originalPath = [];
|
||||
this.keyString = '';
|
||||
},
|
||||
updateSelection(selection) {
|
||||
if (selection.length === 0) {
|
||||
this.domainObject = {};
|
||||
this.originalLocation = [];
|
||||
if (!selection.length) {
|
||||
this.clearData();
|
||||
return;
|
||||
} else if (!selection[0].context.item && selection[1] && selection[1].context.item) {
|
||||
this.setOriginalPath([selection[1].context.item], true);
|
||||
return;
|
||||
}
|
||||
|
||||
this.domainObject = selection[0].context.item;
|
||||
|
||||
|
||||
let keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
||||
if (this.keyString !== keyString) {
|
||||
if (keyString && this.keyString !== keyString) {
|
||||
this.keyString = keyString;
|
||||
this.originalPath = [];
|
||||
|
||||
|
@ -112,7 +112,7 @@ const PLACEHOLDER_OBJECT = {};
|
||||
promptUserandCancelEditing() {
|
||||
let dialog = this.openmct.overlays.dialog({
|
||||
iconClass: 'alert',
|
||||
message: 'Are you sure you want to continue? All unsaved changes will be lost!',
|
||||
message: 'Any unsaved changes will be lost. Are you sure you want to continue?',
|
||||
buttons: [
|
||||
{
|
||||
label: 'Ok',
|
||||
|
@ -8,7 +8,7 @@
|
||||
v-if="opened">
|
||||
<div class="c-super-menu__menu">
|
||||
<ul>
|
||||
<li v-for="(item, index) in items"
|
||||
<li v-for="(item, index) in sortedItems"
|
||||
:key="index"
|
||||
:class="item.class"
|
||||
:title="item.title"
|
||||
@ -145,6 +145,19 @@
|
||||
selectedMenuItem: {},
|
||||
opened: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sortedItems () {
|
||||
return this.items.sort((a,b) => {
|
||||
if (a.name < b.name) {
|
||||
return -1;
|
||||
} else if (a.name > b.name) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -95,6 +95,7 @@
|
||||
.l-pane__contents {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
overflow-x: hidden;
|
||||
|
||||
> * {
|
||||
flex: 0 0 auto;
|
||||
@ -186,7 +187,6 @@
|
||||
// Wrapper for main views
|
||||
flex: 1 1 auto !important;
|
||||
overflow: auto;
|
||||
//font-size: 16px; // TEMP FOR LEGACY STYLING
|
||||
}
|
||||
|
||||
&__tree {
|
||||
@ -209,6 +209,8 @@
|
||||
&__main {
|
||||
// Top and bottom padding in container that holds tree, __pane-main and Inspector
|
||||
padding: $shellMainPad;
|
||||
min-height: 0;
|
||||
|
||||
> .l-pane {
|
||||
padding-top: 0;
|
||||
padding-bottom: 0;
|
||||
@ -240,7 +242,10 @@
|
||||
|
||||
.is-editing {
|
||||
.l-shell__main-container {
|
||||
$m: 3px;
|
||||
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdw;
|
||||
margin-left: $m;
|
||||
margin-right: $m;
|
||||
|
||||
&[s-selected] {
|
||||
// Provide a clearer selection context articulation for the main edit area
|
||||
|
@ -7,10 +7,17 @@
|
||||
@clear="searchTree">
|
||||
</search>
|
||||
</div>
|
||||
|
||||
<!-- loading -->
|
||||
<div class="c-tree-and-search__loading loading"
|
||||
v-if="isLoading"></div>
|
||||
<!-- end loading -->
|
||||
|
||||
<div class="c-tree-and-search__no-results" v-if="treeItems.length === 0">
|
||||
No results found
|
||||
</div>
|
||||
<ul class="c-tree-and-search__tree c-tree">
|
||||
<ul class="c-tree-and-search__tree c-tree"
|
||||
v-if="!isLoading">
|
||||
<tree-item v-for="treeItem in treeItems"
|
||||
:key="treeItem.id"
|
||||
:node="treeItem">
|
||||
@ -34,6 +41,10 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__loading {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&__no-results {
|
||||
font-style: italic;
|
||||
opacity: 0.6;
|
||||
@ -47,10 +58,16 @@
|
||||
|
||||
.c-tree {
|
||||
@include userSelectNone();
|
||||
height: 100%; // Chrome 73 overflow bug fix
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
padding-right: $interiorMargin;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
&.c-tree__item-h { display: block; }
|
||||
}
|
||||
|
||||
.c-tree {
|
||||
margin-left: 15px;
|
||||
}
|
||||
@ -168,7 +185,8 @@
|
||||
return {
|
||||
searchValue: '',
|
||||
allTreeItems: [],
|
||||
filteredTreeItems: []
|
||||
filteredTreeItems: [],
|
||||
isLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -182,9 +200,13 @@
|
||||
},
|
||||
methods: {
|
||||
getAllChildren() {
|
||||
this.isLoading = true;
|
||||
this.openmct.objects.get('ROOT')
|
||||
.then(root => this.openmct.composition.get(root).load())
|
||||
.then(root => {
|
||||
return this.openmct.composition.get(root).load()
|
||||
})
|
||||
.then(children => {
|
||||
this.isLoading = false;
|
||||
this.allTreeItems = children.map(c => {
|
||||
return {
|
||||
id: this.openmct.objects.makeKeyString(c.identifier),
|
||||
|
@ -128,7 +128,6 @@
|
||||
background: $colorSplitterBg;
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
transition: $transOut;
|
||||
|
||||
&:before {
|
||||
|
@ -11,10 +11,15 @@
|
||||
</object-label>
|
||||
</div>
|
||||
<ul v-if="expanded" class="c-tree">
|
||||
<li class="c-tree__item-h"
|
||||
v-if="isLoading && !loaded">
|
||||
<div class="c-tree__item loading">
|
||||
<span class="c-tree__item__label">Loading...</span>
|
||||
</div>
|
||||
</li>
|
||||
<tree-item v-for="child in children"
|
||||
:key="child.id"
|
||||
:node="child"
|
||||
>
|
||||
:node="child">
|
||||
</tree-item>
|
||||
</ul>
|
||||
</li>
|
||||
@ -50,7 +55,7 @@
|
||||
}
|
||||
let parentKeyString = this.openmct.objects.makeKeyString(parent.identifier);
|
||||
return parentKeyString !== this.node.object.location;
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// TODO: should update on mutation.
|
||||
@ -88,7 +93,8 @@
|
||||
this.composition = this.openmct.composition.get(this.domainObject);
|
||||
this.composition.on('add', this.addChild);
|
||||
this.composition.on('remove', this.removeChild);
|
||||
this.composition.load().then(this.finishLoading());
|
||||
this.composition.load().then(this.finishLoading);
|
||||
this.isLoading = true;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -60,6 +60,10 @@ class ApplicationRouter extends EventEmitter {
|
||||
}
|
||||
|
||||
handleLocationChange(pathString) {
|
||||
if (pathString[0] !== '/') {
|
||||
pathString = '/' + pathString
|
||||
}
|
||||
|
||||
let url = new URL(
|
||||
pathString,
|
||||
`${location.protocol}//${location.host}${location.pathname}`
|
||||
|
@ -42,20 +42,23 @@ define([
|
||||
// navigation service and router to expose a clear and minimal
|
||||
// API for this.
|
||||
openmct.router.path = objects.reverse();
|
||||
|
||||
|
||||
unobserve = this.openmct.objects.observe(openmct.router.path[0], '*', (newObject) => {
|
||||
openmct.router.path[0] = newObject;
|
||||
});
|
||||
|
||||
openmct.layout.$refs.browseBar.domainObject = navigatedObject;
|
||||
browseObject = navigatedObject;
|
||||
|
||||
if (!navigatedObject) {
|
||||
openmct.layout.$refs.browseObject.clear();
|
||||
return;
|
||||
}
|
||||
let currentProvider = openmct
|
||||
.objectViews
|
||||
.getByProviderKey(currentViewKey)
|
||||
.getByProviderKey(currentViewKey);
|
||||
|
||||
document.title = browseObject.name; //change document title to current object in main view
|
||||
|
||||
if (currentProvider && currentProvider.canView(navigatedObject)) {
|
||||
viewObject(navigatedObject, currentProvider);
|
||||
|
Reference in New Issue
Block a user