Compare commits

..

7 Commits

Author SHA1 Message Date
charlesh88
38c1a981e8 Clock element as a standalone component
- Was intended to replace clock indicator;
- WIP!
2019-06-25 10:10:58 -07:00
charlesh88
50944cfed0 Status bar migration to top of layout, WIP
- Added tracking style to indicator-template;
- Moved click action to button in label of globalClearIndicator;
- Removed unnecessary markup in Indicators.vue;
- Commented out __head collapse button for now in Layout.vue;
2019-06-07 19:04:30 -07:00
charlesh88
27b236ffe4 Status bar migration to top of layout, WIP
- Refine styles and markup for Indicators;
- Better separation of styles for clickable and non-clickable
Indicators;
2019-06-07 18:30:08 -07:00
charlesh88
b7e75bcc22 Status bar migration to top of layout, WIP
- Refine and remove legacy styles for Indicators;
- Significant cleanup in Indicator markup;
- Remove unnecessary wrapper component StatusBar.vue;
- Move collapse-button styles to a more general location in _controls
.scss;
- New hasMenu mixin to allow easier application of disclosure control
styling;
2019-06-07 16:07:50 -07:00
Deep Tailor
210a23dfe2 styling 2019-06-06 15:29:19 -07:00
Deep Tailor
84bfb9e8cc global clear works on plots 2019-06-06 15:06:03 -07:00
Deep Tailor
fd749253d9 first proto of global clear, working on tables 2019-06-06 14:38:41 -07:00
69 changed files with 686 additions and 1547 deletions

View File

@@ -99,10 +99,10 @@ define([
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
return _.extend(
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]
);
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]
);
};
return GeneratorMetadataProvider;

View File

@@ -1,9 +1,9 @@
<span class="h-indicator" ng-controller="DialogLaunchController">
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div class="c-indicator c-indicator--clickable icon-box-with-arrow s-status-available"><span class="label c-indicator__label">
<button ng-click="launchProgress(true)">Known</button>
<button ng-click="launchProgress(false)">Unknown</button>
<button ng-click="launchError()">Error</button>
<button ng-click="launchInfo()">Info</button>
<div class="c-indicator c-indicator--clickable icon-box-with-arrow s-status-available"><span class="label">
<a ng-click="launchProgress(true)">Known</a>
<a ng-click="launchProgress(false)">Unknown</a>
<a ng-click="launchError()">Error</a>
<a ng-click="launchInfo()">Info</a>
</span></div>
</span>

View File

@@ -1,9 +1,9 @@
<span class="h-indicator" ng-controller="NotificationLaunchController">
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div class="c-indicator c-indicator--clickable icon-bell s-status-available"><span class="label c-indicator__label">
<button ng-click="newInfo()">Success</button>
<button ng-click="newError()">Error</button>
<button ng-click="newAlert()">Alert</button>
<button ng-click="newProgress()">Progress</button>
<div class="c-indicator c-indicator--clickable icon-bell s-status-available"><span class="label">
<a ng-click="newInfo()">Success</a>
<a ng-click="newError()">Error</a>
<a ng-click="newAlert()">Alert</a>
<a ng-click="newProgress()">Progress</a>
</span></div>
</span>

View File

@@ -50,6 +50,7 @@
openmct.install(openmct.plugins.Generator());
openmct.install(openmct.plugins.ExampleImagery());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.ImportExport());
openmct.install(openmct.plugins.AutoflowView({
type: "telemetry.panel"
}));
@@ -79,9 +80,14 @@
}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.install(openmct.plugins.FolderView());
openmct.install(openmct.plugins.Tabs());
openmct.install(openmct.plugins.FlexibleLayout());
openmct.install(openmct.plugins.LADTable());
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
openmct.install(openmct.plugins.ObjectMigration());
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
openmct.install(openmct.plugins.GoToOriginalAction());
openmct.install(openmct.plugins.GlobalClearIndicator());
openmct.start();
</script>
</html>

View File

@@ -4,7 +4,6 @@
"description": "The Open MCT core platform",
"dependencies": {},
"devDependencies": {
"acorn": "6.2.0",
"angular": "1.4.14",
"angular-route": "1.4.14",
"babel-eslint": "8.2.6",
@@ -56,7 +55,7 @@
"node-bourbon": "^4.2.3",
"node-sass": "^4.9.2",
"painterro": "^0.2.65",
"printj": "^1.2.1",
"printj": "^1.1.0",
"raw-loader": "^0.5.1",
"request": "^2.69.0",
"split": "^1.0.0",

View File

@@ -23,5 +23,5 @@
<div class="c-indicator {{ngModel.getCssClass()}}"
title="{{ngModel.getDescription()}}"
ng-show="ngModel.getText().length > 0">
<span class="label c-indicator__label">{{ngModel.getText()}}</span>
<span class="label">{{ngModel.getText()}}</span>
</div>

View File

@@ -1,8 +1,8 @@
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div ng-show="notifications.length > 0" class="c-indicator c-indicator--clickable s-status-{{highest.severity}} icon-bell"
ng-controller="NotificationIndicatorController">
<span class="label c-indicator__label">
<button ng-click="showNotificationsList()">
{{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span></button>
</span><span class="c-indicator__count">{{notifications.length}}</span>
<span class="label">
<a ng-click="showNotificationsList()">
{{notifications.length}} Notification<span ng-show="notifications.length > 1">s</span></a>
</span><span class="count">{{notifications.length}}</span>
</div>

View File

@@ -49,7 +49,7 @@ define(
};
ClockIndicator.prototype.getCssClass = function () {
return "t-indicator-clock icon-clock no-minify c-indicator--not-clickable";
return "t-indicator-clock icon-clock no-collapse c-indicator--not-clickable";
};
ClockIndicator.prototype.getText = function () {

View File

@@ -64,30 +64,12 @@ define(['zepto'], function ($) {
var tree = this.generateNewIdentifiers(objTree);
var rootId = tree.rootId;
var rootObj = this.instantiate(tree.openmct[rootId], rootId);
var newStyleParent = parent.useCapability('adapter');
var newStyleRootObj = rootObj.useCapability('adapter');
if (this.openmct.composition.checkPolicy(newStyleParent, newStyleRootObj)) {
// Instantiate all objects in tree with their newly generated ids,
// adding each to its rightful parent's composition
rootObj.getCapability("location").setPrimaryLocation(parent.getId());
this.deepInstantiate(rootObj, tree.openmct, []);
parent.getCapability("composition").add(rootObj);
} else {
var dialog = this.openmct.overlays.dialog({
iconClass: 'alert',
message: "We're sorry, but you cannot import that object type into this object.",
buttons: [
{
label: "Ok",
emphasis: true,
callback: function () {
dialog.dismiss();
}
}
]
});
}
// Instantiate all objects in tree with their newly genereated ids,
// adding each to its rightful parent's composition
rootObj.getCapability("location").setPrimaryLocation(parent.getId());
this.deepInstantiate(rootObj, tree.openmct, []);
parent.getCapability("composition").add(rootObj);
};
ImportAsJSONAction.prototype.deepInstantiate = function (parent, tree, seen) {

View File

@@ -246,21 +246,12 @@ define([
this.branding = BrandingAPI.default;
this.legacyRegistry = defaultRegistry;
// Plugin's that are installed by default
this.install(this.plugins.Plot());
this.install(this.plugins.TelemetryTable());
this.install(PreviewPlugin.default());
this.install(LegacyIndicatorsPlugin());
this.install(LicensesPlugin.default());
this.install(RemoveActionPlugin.default());
this.install(this.plugins.ImportExport());
this.install(this.plugins.FolderView());
this.install(this.plugins.Tabs());
this.install(this.plugins.FlexibleLayout());
this.install(this.plugins.LADTable());
this.install(this.plugins.GoToOriginalAction());
if (typeof BUILD_CONSTANTS !== 'undefined') {
this.install(buildInfoPlugin(BUILD_CONSTANTS));

View File

@@ -108,9 +108,6 @@ define([
link();
}
},
onClearData() {
scope.$broadcast('clearData');
},
destroy: function () {
element.off();
element.remove();

View File

@@ -25,7 +25,7 @@ define([
cssClass: representation.cssClass,
description: representation.description,
canView: function (selection) {
if (selection.length !== 1 || selection[0].length === 0) {
if (selection.length === 0 || selection[0].length === 0) {
return false;
}

View File

@@ -28,7 +28,7 @@ define(['zepto', './res/indicator-template.html'],
this.openmct = openmct;
this.element = $(indicatorTemplate)[0];
this.textElement = this.element.querySelector('.js-indicator-text');
this.textElement = this.element.querySelector('.indicator-text');
//Set defaults
this.text('New Indicator');

View File

@@ -1,3 +1,3 @@
<div class="c-indicator c-indicator--clickable c-indicator--simple" title="">
<span class="label js-indicator-text c-indicator__label"></span>
<span class="label indicator-text"></span>
</div>

View File

@@ -93,7 +93,7 @@
&.message-severity-error:before {
@include legacyMessage();
content: $glyph-icon-alert-triangle;
color: $colorWarningHi;
color: $colorWarningLo;
}
// Messages in a list

View File

@@ -69,7 +69,6 @@
flex: 1 1 auto;
display: flex;
flex-direction: column;
overflow: hidden;
}
&__top-bar {

View File

@@ -1,39 +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.
*****************************************************************************/
export default class ClearDataAction {
constructor(openmct, appliesToObjects) {
this.name = 'Clear Data';
this.description = 'Clears current data for object, unsubscribes and resubscribes to data';
this._openmct = openmct;
this._appliesToObjects = appliesToObjects;
}
invoke(objectPath) {
this._openmct.objectViews.emit('clearData', objectPath[0]);
}
appliesTo(objectPath) {
let contextualDomainObject = objectPath[0];
return this._appliesToObjects.filter(type => contextualDomainObject.type === type).length;
}
}

View File

@@ -1,62 +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.
*****************************************************************************/
import ClearDataActionPlugin from '../plugin.js';
import ClearDataAction from '../clearDataAction.js';
describe('When the Clear Data Plugin is installed,', function () {
var mockObjectViews = jasmine.createSpyObj('objectViews', ['emit']),
mockIndicatorProvider = jasmine.createSpyObj('indicators', ['add']),
mockContextMenuProvider = jasmine.createSpyObj('contextMenu', ['registerAction']),
openmct = {
objectViews: mockObjectViews,
indicators: mockIndicatorProvider,
contextMenu: mockContextMenuProvider,
install: function (plugin) {
plugin(this);
}
},
mockObjectPath = [
{name: 'mockObject1'},
{name: 'mockObject2'}
];
it('Global Clear Indicator is installed', function () {
openmct.install(ClearDataActionPlugin([]));
expect(mockIndicatorProvider.add).toHaveBeenCalled();
});
it('Clear Data context menu action is installed', function () {
openmct.install(ClearDataActionPlugin([]));
expect(mockContextMenuProvider.registerAction).toHaveBeenCalled();
});
it('clear data action emits a clearData event when invoked', function () {
let action = new ClearDataAction(openmct);
action.invoke(mockObjectPath);
expect(mockObjectViews.emit).toHaveBeenCalledWith('clearData', mockObjectPath[0]);
});
});

View File

@@ -1,77 +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([
'./components/AlphanumericFormatView.vue',
'vue'
], function (AlphanumericFormatView, Vue) {
function AlphanumericFormatViewProvider(openmct, options) {
function isTelemetryObject(selectionPath) {
let selectedObject = selectionPath[0].context.item;
let parentObject = selectionPath[1].context.item;
return parentObject &&
parentObject.type === 'layout' &&
selectedObject &&
openmct.telemetry.isTelemetryObject(selectedObject) &&
!options.showAsView.includes(selectedObject.type)
}
return {
key: 'alphanumeric-format',
name: 'Alphanumeric Format',
canView: function (selection) {
if (selection.length === 0 || selection[0].length === 1) {
return false;
}
return selection.every(isTelemetryObject);
},
view: function (selection) {
let component;
return {
show: function (element) {
component = new Vue({
provide: {
openmct
},
components: {
AlphanumericFormatView: AlphanumericFormatView.default
},
template: '<alphanumeric-format-view></alphanumeric-format-view>',
el: element
});
},
destroy: function () {
component.$destroy();
component = undefined;
}
}
},
priority: function () {
return 1;
}
}
}
return AlphanumericFormatViewProvider;
});

View File

@@ -1,90 +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.
*****************************************************************************/
<template>
<div class="c-properties" v-if="isEditing">
<div class="c-properties__header">Alphanumeric Format</div>
<ul class="c-properties__section">
<li class="c-properties__row">
<div class="c-properties__label" title="Printf formatting for the selected telemetry">
<label for="telemetryPrintfFormat">Format</label>
</div>
<div class="c-properties__value">
<input id="telemetryPrintfFormat"
type="text"
@change="formatTelemetry"
:value="telemetryFormat"
:placeholder="nonMixedFormat ? '' : 'Mixed'"
>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
inject: ['openmct'],
data() {
let selectionPath = this.openmct.selection.get()[0];
return {
isEditing: this.openmct.editor.isEditing(),
telemetryFormat: undefined,
nonMixedFormat: false
}
},
methods: {
toggleEdit(isEditing) {
this.isEditing = isEditing;
},
formatTelemetry(event) {
let newFormat = event.currentTarget.value;
this.openmct.selection.get().forEach(selectionPath => {
selectionPath[0].context.updateTelemetryFormat(newFormat);
});
this.telemetryFormat = newFormat;
},
handleSelection(selection) {
if (selection.length === 0 || selection[0].length < 2) {
return;
}
let format = selection[0][0].context.layoutItem.format;
this.nonMixedFormat = selection.every(selectionPath => {
return selectionPath[0].context.layoutItem.format === format;
});
this.telemetryFormat = this.nonMixedFormat ? format : '';
}
},
mounted() {
this.openmct.editor.on('isEditing', this.toggleEdit);
this.openmct.selection.on('change', this.handleSelection);
this.handleSelection(this.openmct.selection.get());
},
destroyed() {
this.openmct.editor.off('isEditing', this.toggleEdit);
this.openmct.selection.off('change', this.handleSelection);
}
}
</script>

View File

@@ -48,8 +48,7 @@
:multiSelect="selectedLayoutItems.length > 1"
@move="move"
@endMove="endMove"
@endLineResize='endLineResize'
@formatChanged='updateTelemetryFormat'>
@endLineResize='endLineResize'>
</component>
<edit-marquee v-if='showMarquee'
:gridSize="gridSize"
@@ -558,11 +557,6 @@
this.layoutItems.splice(itemIndex, 1);
this.layoutItems.splice(newIndex, 0, items[itemIndex]);
}
},
updateTelemetryFormat(item, format) {
let index = _.findIndex(this.layoutItems, item);
item.format = format;
this.mutate(`configuration.items[${index}]`, item);
}
},
mounted() {

View File

@@ -79,7 +79,6 @@
<script>
import LayoutFrame from './LayoutFrame.vue'
import printj from 'printj'
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
DEFAULT_POSITION = [1, 1];
@@ -144,10 +143,6 @@
return;
}
if (this.item.format) {
return printj.sprintf(this.item.format, this.datum[this.valueMetadata.key]);
}
return this.valueFormatter && this.valueFormatter.format(this.datum);
},
telemetryClass() {
@@ -173,9 +168,6 @@
}
this.context.index = newIndex;
},
item(newItem) {
this.context.layoutItem = newItem;
}
},
methods: {
@@ -227,14 +219,10 @@
this.context = {
item: domainObject,
layoutItem: this.item,
index: this.index,
updateTelemetryFormat: this.updateTelemetryFormat
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, this.context, this.initSelect);
},
updateTelemetryFormat(format) {
this.$emit('formatChanged', this.item, format);
}
},
mounted() {

View File

@@ -25,8 +25,6 @@ import Vue from 'vue'
import objectUtils from '../../api/objects/object-utils.js'
import DisplayLayoutType from './DisplayLayoutType.js'
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
import AlphaNumericFormatViewProvider from './AlphanumericFormatViewProvider.js'
export default function DisplayLayoutPlugin(options) {
return function (openmct) {
openmct.objectViews.addProvider({
@@ -78,8 +76,7 @@ export default function DisplayLayoutPlugin(options) {
}
});
openmct.types.addType('layout', DisplayLayoutType());
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct, options));
openmct.inspectorViews.addProvider(new AlphaNumericFormatViewProvider(openmct, options));
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct));
openmct.composition.addPolicy((parent, child) => {
if (parent.type === 'layout' && child.type === 'folder') {
return false;

View File

@@ -63,13 +63,7 @@ export default {
if (filterValue && filterValue[comparator]) {
if (value === false) {
let filteredValueName = filterValue[comparator].filter(v => v !== valueName);
if (filteredValueName.length === 0) {
delete this.updatedFilters[key];
} else {
filterValue[comparator] = filteredValueName;
}
filterValue[comparator] = filterValue[comparator].filter(v => v !== valueName);
} else {
filterValue[comparator].push(valueName);
}
@@ -83,14 +77,6 @@ export default {
this.$emit('updateFilters', this.keyString, this.updatedFilters);
},
updateTextFilter(key, comparator, value) {
if (value.trim() === '') {
if (this.updatedFilters[key]) {
delete this.updatedFilters[key];
this.$emit('updateFilters', this.keyString, this.updatedFilters);
}
return;
}
if (!this.updatedFilters[key]) {
this.$set(this.updatedFilters, key, {});
this.$set(this.updatedFilters[key], comparator, '');

View File

@@ -59,18 +59,14 @@ export default {
removeChildren(identifier) {
let keyString = this.openmct.objects.makeKeyString(identifier);
this.$delete(this.children, keyString);
delete this.persistedFilters[keyString];
this.mutateConfigurationFilters();
this.persistFilters(keyString);
},
persistFilters(keyString, userSelects) {
this.persistedFilters[keyString] = userSelects;
this.mutateConfigurationFilters();
this.openmct.objects.mutate(this.providedObject, 'configuration.filters', this.persistedFilters);
},
updatePersistedFilters(filters) {
this.persistedFilters = filters;
},
mutateConfigurationFilters() {
this.openmct.objects.mutate(this.providedObject, 'configuration.filters', this.persistedFilters);
}
},
mounted(){

View File

@@ -1,6 +1,6 @@
<template>
<div class="c-indicator c-indicator--clickable icon-session">
<span class="label c-indicator__label">
<span class="label">
<button @click="globalClearEmit">Clear All Data</button>
</span>
</div>
@@ -11,7 +11,7 @@ export default {
inject: ['openmct'],
methods: {
globalClearEmit() {
this.openmct.objectViews.emit('clearData');
this.openmct.notifications.emit('clear');
}
}
}

View File

@@ -22,16 +22,12 @@
define([
'./components/globalClearIndicator.vue',
'./clearDataAction',
'vue'
], function (
GlobaClearIndicator,
ClearDataAction,
Vue
) {
return function plugin(appliesToObjects) {
appliesToObjects = appliesToObjects || [];
return function plugin() {
return function install(openmct) {
let component = new Vue ({
provide: {
@@ -47,8 +43,6 @@ define([
};
openmct.indicators.add(indicator);
openmct.contextMenu.registerAction(new ClearDataAction.default(openmct, appliesToObjects));
};
};
});

View File

@@ -63,11 +63,8 @@ define([
$scope.pending = 0;
this.clearData = this.clearData.bind(this);
this.listenTo($scope, 'user:viewport:change:end', this.onUserViewportChangeEnd, this);
this.listenTo($scope, '$destroy', this.destroy, this);
this.listenTo($scope, 'clearData', this.clearData);
this.config = this.getConfig(this.$scope.domainObject);
this.listenTo(this.config.series, 'add', this.addSeries, this);
@@ -77,13 +74,16 @@ define([
this.followTimeConductor();
this.newStyleDomainObject = $scope.domainObject.useCapability('adapter');
this.keyString = this.openmct.objects.makeKeyString(this.newStyleDomainObject.identifier);
this.filterObserver = this.openmct.objects.observe(
this.newStyleDomainObject,
'configuration.filters',
this.updateFiltersAndResubscribe.bind(this)
);
this.refresh = this.refresh.bind(this);
this.openmct.notifications.on('clear', this.refresh);
}
eventHelpers.extend(PlotController.prototype);
@@ -170,6 +170,8 @@ define([
if (this.filterObserver) {
this.filterObserver();
}
this.openmct.notifications.off('clear', this.refresh);
};
PlotController.prototype.loadMoreData = function (range, purge) {
@@ -267,7 +269,7 @@ define([
});
};
PlotController.prototype.clearData = function () {
PlotController.prototype.refresh = function (updatedFilters) {
this.config.series.forEach(function (series) {
series.refresh();
});

View File

@@ -44,7 +44,7 @@ define([
'./filters/plugin',
'./objectMigration/plugin',
'./goToOriginalAction/plugin',
'./clearData/plugin'
'./globalClearIndicator/plugin'
], function (
_,
UTCTimeSystem,
@@ -69,7 +69,7 @@ define([
Filters,
ObjectMigration,
GoToOriginalAction,
ClearData
GlobalClearIndicator
) {
var bundleMap = {
LocalStorage: 'platform/persistence/local',
@@ -168,7 +168,7 @@ define([
plugins.Filters = Filters;
plugins.ObjectMigration = ObjectMigration.default;
plugins.GoToOriginalAction = GoToOriginalAction.default;
plugins.ClearData = ClearData;
plugins.GlobalClearIndicator = GlobalClearIndicator;
return plugins;
});

View File

@@ -37,7 +37,7 @@ define([
key: 'table-configuration',
name: 'Telemetry Table Configuration',
canView: function (selection) {
if (selection.length !== 1 || selection[0].length === 0) {
if (selection.length === 0 || selection[0].length === 0) {
return false;
}
let object = selection[0][0].context.item;

View File

@@ -26,7 +26,6 @@ define([
'./collections/BoundedTableRowCollection',
'./collections/FilteredTableRowCollection',
'./TelemetryTableRow',
'./TelemetryTableColumn',
'./TelemetryTableConfiguration'
], function (
EventEmitter,
@@ -34,7 +33,6 @@ define([
BoundedTableRowCollection,
FilteredTableRowCollection,
TelemetryTableRow,
TelemetryTableColumn,
TelemetryTableConfiguration
) {
class TelemetryTable extends EventEmitter {
@@ -49,8 +47,6 @@ define([
this.telemetryObjects = [];
this.outstandingRequests = 0;
this.configuration = new TelemetryTableConfiguration(domainObject, openmct);
this.paused = false;
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
this.addTelemetryObject = this.addTelemetryObject.bind(this);
this.removeTelemetryObject = this.removeTelemetryObject.bind(this);
@@ -66,6 +62,7 @@ define([
openmct.time.on('bounds', this.refreshData);
openmct.time.on('timeSystem', this.refreshData);
openmct.notifications.on('clear', this.refreshData);
}
initialize() {
@@ -98,6 +95,8 @@ define([
this.tableComposition.load().then((composition) => {
composition = composition.filter(this.isTelemetryObject);
this.configuration.addColumnsForAllObjects(composition);
composition.forEach(this.addTelemetryObject);
this.tableComposition.on('add', this.addTelemetryObject);
@@ -107,7 +106,7 @@ define([
}
addTelemetryObject(telemetryObject) {
this.addColumnsForObject(telemetryObject, true);
this.configuration.addColumnsForObject(telemetryObject, true);
this.requestDataFor(telemetryObject);
this.subscribeTo(telemetryObject);
this.telemetryObjects.push(telemetryObject);
@@ -146,17 +145,14 @@ define([
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
let columnMap = this.getColumnMapForObject(keyString);
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
this.processHistoricalData(telemetryData, columnMap, keyString, limitEvaluator);
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
this.boundedRows.add(telemetryRows);
}).finally(() => {
this.decrementOutstandingRequests();
});
}
processHistoricalData(telemetryData, columnMap, keyString, limitEvaluator) {
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
this.boundedRows.add(telemetryRows);
}
/**
* @private
*/
@@ -196,19 +192,6 @@ define([
}, {});
}
addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
metadataValues.forEach(metadatum => {
let column = this.createColumn(metadatum);
this.configuration.addSingleColumnForObject(telemetryObject, column);
});
}
createColumn(metadatum) {
return new TelemetryTableColumn(this.openmct, metadatum);
}
subscribeTo(telemetryObject) {
let subscribeOptions = this.buildOptionsFromConfiguration(telemetryObject);
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
@@ -220,17 +203,10 @@ define([
if (!this.telemetryObjects.includes(telemetryObject)) {
return;
}
if (!this.paused) {
this.processRealtimeDatum(datum, columnMap, keyString, limitEvaluator);
}
this.boundedRows.add(new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
}, subscribeOptions);
}
processRealtimeDatum(datum, columnMap, keyString, limitEvaluator) {
this.boundedRows.add(new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
}
isTelemetryObject(domainObject) {
return domainObject.hasOwnProperty('telemetry');
}
@@ -259,24 +235,13 @@ define([
}
}
pause() {
this.paused = true;
this.boundedRows.unsubscribeFromBounds();
}
unpause() {
this.paused = false;
this.boundedRows.subscribeToBounds();
this.refreshData();
}
destroy() {
this.boundedRows.destroy();
this.filteredRows.destroy();
Object.keys(this.subscriptions).forEach(this.unsubscribe, this);
this.openmct.time.off('bounds', this.refreshData);
this.openmct.time.off('timeSystem', this.refreshData);
this.openmct.notifications.off('clear', this.refreshData);
if (this.filterObserver) {
this.filterObserver();
}

View File

@@ -21,11 +21,10 @@
*****************************************************************************/
define(function () {
class TelemetryTableColumn {
constructor (openmct, metadatum, options = {selectable: false}) {
constructor (openmct, metadatum) {
this.metadatum = metadatum;
this.formatter = openmct.telemetry.getValueFormatter(metadatum);
this.titleValue = this.metadatum.name;
this.selectable = options.selectable;
}
getKey() {
@@ -56,7 +55,8 @@ define(function () {
return formattedValue;
}
}
}
};
return TelemetryTableColumn;
});

View File

@@ -22,8 +22,9 @@
define([
'lodash',
'EventEmitter'
], function (_, EventEmitter) {
'EventEmitter',
'./TelemetryTableColumn'
], function (_, EventEmitter, TelemetryTableColumn) {
class TelemetryTableConfiguration extends EventEmitter {
constructor(domainObject, openmct) {
@@ -33,6 +34,7 @@ define([
this.openmct = openmct;
this.columns = {};
this.addColumnsForObject = this.addColumnsForObject.bind(this);
this.removeColumnsForObject = this.removeColumnsForObject.bind(this);
this.objectMutated = this.objectMutated.bind(this);
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
@@ -46,7 +48,6 @@ define([
configuration.hiddenColumns = configuration.hiddenColumns || {};
configuration.columnWidths = configuration.columnWidths || {};
configuration.columnOrder = configuration.columnOrder || [];
configuration.cellFormat = configuration.cellFormat || {};
configuration.autosize = configuration.autosize === undefined ? true : configuration.autosize;
return configuration;
@@ -64,18 +65,26 @@ define([
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
this.domainObject = object;
//Was it the configuration that changed?
if (object.configuration !== undefined && !_.eq(object.configuration, this.oldConfiguration)) {
if (!_.eq(object.configuration, this.oldConfiguration)) {
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
this.oldConfiguration = JSON.parse(JSON.stringify(this.getConfiguration()));
this.emit('change', object.configuration);
}
}
addSingleColumnForObject(telemetryObject, column, position) {
addColumnsForAllObjects(objects) {
objects.forEach(object => this.addColumnsForObject(object, false));
}
addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
let objectKeyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
this.columns[objectKeyString] = this.columns[objectKeyString] || [];
position = position || this.columns[objectKeyString].length;
this.columns[objectKeyString].splice(position, 0, column);
this.columns[objectKeyString] = [];
metadataValues.forEach(metadatum => {
let column = new TelemetryTableColumn(this.openmct, metadatum);
this.columns[objectKeyString].push(column);
});
}
removeColumnsForObject(objectIdentifier) {

View File

@@ -42,19 +42,12 @@ define([], function () {
return column && column.getFormattedValue(this.datum[key]);
}
getCellComponentName(key) {
let column = this.columns[key];
return column &&
column.getCellComponentName &&
column.getCellComponentName();
}
getRowClass() {
if (!this.rowClass) {
getRowLimitClass() {
if (!this.rowLimitClass) {
let limitEvaluation = this.limitEvaluator.evaluate(this.datum);
this.rowClass = limitEvaluation && limitEvaluation.cssClass;
this.rowLimitClass = limitEvaluation && limitEvaluation.cssClass;
}
return this.rowClass;
return this.rowLimitClass;
}
getCellLimitClasses() {

View File

@@ -22,10 +22,12 @@
define([
'./components/table.vue',
'../../exporters/CSVExporter',
'./TelemetryTable',
'vue'
], function (
TableComponent,
CSVExporter,
TelemetryTable,
Vue
) {
@@ -49,6 +51,7 @@ define([
return domainObject.type === 'table';
},
view(domainObject) {
let csvExporter = new CSVExporter.default();
let table = new TelemetryTable(domainObject, openmct);
let component;
return {
@@ -64,18 +67,16 @@ define([
},
provide: {
openmct,
csvExporter,
table
},
el: element,
template: '<table-component :isEditing="isEditing" :enableMarking="true"></table-component>'
template: '<table-component :isEditing="isEditing"></table-component>'
});
},
onEditModeChange(isEditing) {
component.isEditing = isEditing;
},
onClearData() {
table.refreshData();
},
destroy: function (element) {
component.$destroy();
component = undefined;

View File

@@ -43,8 +43,7 @@ define(
this.sortByTimeSystem(openmct.time.timeSystem());
this.lastBounds = openmct.time.bounds();
this.subscribeToBounds();
openmct.time.on('bounds', this.bounds);
}
addOne(item) {
@@ -141,16 +140,8 @@ define(
return this.parseTime(row.datum[this.sortOptions.key]);
}
unsubscribeFromBounds() {
this.openmct.time.off('bounds', this.bounds);
}
subscribeToBounds() {
this.openmct.time.on('bounds', this.bounds);
}
destroy() {
this.unsubscribeFromBounds();
this.openmct.time.off('bounds', this.bounds);
}
}
return BoundedTableRowCollection;

View File

@@ -1,176 +0,0 @@
<template>
<div v-if="filterNames.length > 0"
:title=title
class="c-filter-indication"
:class="{ 'c-filter-indication--mixed': mixed }">
<span class="c-filter-indication__mixed">{{ label }}</span>
<span v-for="(name, index) in filterNames"
class="c-filter-indication__label">
{{ name }}
</span>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-filter-indication {
@include userSelectNone();
background: $colorFilterBg;
color: $colorFilterFg;
display: flex;
align-items: center;
font-size: 0.9em;
margin-top: $interiorMarginSm;
padding: 2px;
text-transform: uppercase;
&:before {
font-family: symbolsfont-12px;
content: $glyph-icon-filter;
display: block;
font-size: 12px;
margin-right: $interiorMarginSm;
}
&__mixed {
font-weight: bold;
margin-right: $interiorMarginSm;
}
&--mixed {
.c-filter-indication__mixed {
font-style: italic;
}
}
&__label {
+ .c-filter-indication__label {
&:before {
content: ',';
}
}
}
}
</style>
<script>
const FILTER_INDICATOR_LABEL = 'Filters:';
const FILTER_INDICATOR_LABEL_MIXED = 'Mixed Filters:';
const FILTER_INDICATOR_TITLE = 'Data filters are being applied to this view.';
const FILTER_INDICATOR_TITLE_MIXED = 'A mix of data filter values are being applied to this view.';
export default {
inject: ['openmct', 'table'],
data() {
return {
filterNames: [],
filteredTelemetry: {},
mixed: false,
label: '',
title: ''
}
},
methods: {
isTelemetryObject(domainObject) {
return domainObject.hasOwnProperty('telemetry');
},
setFilterNames() {
let names = [];
this.composition && this.composition.load().then((domainObjects) => {
domainObjects.forEach(telemetryObject => {
let keyString= this.openmct.objects.makeKeyString(telemetryObject.identifier);
let filters = this.filteredTelemetry[keyString];
this.telemetryKeyStrings.add(keyString);
if (filters !== undefined) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
Object.keys(filters).forEach(key => {
metadataValues.forEach(metadaum => {
if (key === metadaum.key) {
names.push(metadaum.name);
}
});
});
}
});
this.filterNames = Array.from(new Set(names));
});
},
handleConfigurationChanges(configuration) {
if (!_.eq(this.filteredTelemetry, configuration.filters)) {
this.updateFilters(configuration.filters || {});
}
},
checkFiltersForMixedValues() {
let valueToCompare = this.filteredTelemetry[Object.keys(this.filteredTelemetry)[0]];
let mixed = false;
Object.values(this.filteredTelemetry).forEach(value => {
if (!_.isEqual(valueToCompare, value)) {
mixed = true;
return;
}
});
// If the filtered telemetry is not mixed at this point, check the number of available objects
// with the number of filtered telemetry. If they are not equal, the filters must be mixed.
if (mixed === false && _.size(this.filteredTelemetry) !== this.telemetryKeyStrings.size) {
mixed = true;
}
this.mixed = mixed;
},
setLabels() {
if (this.mixed) {
this.label = FILTER_INDICATOR_LABEL_MIXED;
this.title = FILTER_INDICATOR_TITLE_MIXED;
} else {
this.label = FILTER_INDICATOR_LABEL;
this.title = FILTER_INDICATOR_TITLE;
}
},
updateFilters(filters) {
this.filteredTelemetry = JSON.parse(JSON.stringify(filters));
this.setFilterNames();
this.updateIndicatorLabel();
},
addChildren(child) {
let keyString = this.openmct.objects.makeKeyString(child.identifier);
this.telemetryKeyStrings.add(keyString);
this.updateIndicatorLabel();
},
removeChildren(identifier) {
let keyString = this.openmct.objects.makeKeyString(identifier);
this.telemetryKeyStrings.delete(keyString);
this.updateIndicatorLabel();
},
updateIndicatorLabel() {
this.checkFiltersForMixedValues();
this.setLabels();
}
},
mounted() {
let filters = this.table.configuration.getConfiguration().filters || {};
this.telemetryKeyStrings = new Set();
this.composition = this.openmct.composition.get(this.table.configuration.domainObject);
if (this.composition) {
this.composition.on('add', this.addChildren);
this.composition.on('remove', this.removeChildren);
}
this.table.configuration.on('change', this.handleConfigurationChanges);
this.updateFilters(filters);
},
destroyed() {
this.table.configuration.off('change', this.handleConfigurationChanges);
if (this.composition) {
this.composition.off('add', this.addChildren);
this.composition.off('remove', this.removeChildren);
}
}
}
</script>

View File

@@ -1,44 +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.
*****************************************************************************/
<template>
<td>{{formattedValue}}</td>
</template>
<script>
export default {
inject: ['openmct'],
props: {
row: {
type: Object,
required: true
},
columnKey: {
type: String,
require: true
}
},
computed: {
formattedValue() {
return this.row.getFormattedValue(this.columnKey);
}
}
};
</script>

View File

@@ -23,8 +23,6 @@
</style>
<script>
import TelemetryTableColumn from '../TelemetryTableColumn';
export default {
inject: ['tableConfiguration', 'openmct'],
data() {
@@ -45,7 +43,7 @@ export default {
this.tableConfiguration.updateConfiguration(this.configuration);
},
addObject(domainObject) {
this.addColumnsForObject(domainObject, true);
this.tableConfiguration.addColumnsForObject(domainObject, true);
this.updateHeaders(this.tableConfiguration.getAllHeaders());
},
removeObject(objectIdentifier) {
@@ -58,17 +56,6 @@ export default {
toggleAutosize() {
this.configuration.autosize = !this.configuration.autosize;
this.tableConfiguration.updateConfiguration(this.configuration);
},
addColumnsForAllObjects(objects) {
objects.forEach(object => this.addColumnsForObject(object, false));
},
addColumnsForObject(telemetryObject) {
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
metadataValues.forEach(metadatum => {
let column = new TelemetryTableColumn(this.openmct, metadatum);
this.tableConfiguration.addSingleColumnForObject(telemetryObject, column);
});
}
},
mounted() {
@@ -78,7 +65,7 @@ export default {
compositionCollection.load()
.then((composition) => {
this.addColumnsForAllObjects(composition);
this.tableConfiguration.addColumnsForAllObjects(composition);
this.updateHeaders(this.tableConfiguration.getAllHeaders());
compositionCollection.on('add', this.addObject);

View File

@@ -20,56 +20,26 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<tr :style="{ top: rowTop }"
class="noselect"
:class="[
rowClass,
{'is-selected': marked}
]"
@click="markRow">
<component v-for="(title, key) in headers"
<tr :style="{ top: rowTop }" :class="rowLimitClass">
<td v-for="(title, key) in headers"
:key="key"
:is="componentList[key]"
:columnKey="key"
:style="columnWidths[key] === undefined ? {} : { width: columnWidths[key] + 'px', 'max-width': columnWidths[key] + 'px'}"
:title="formattedRow[key]"
:class="[cellLimitClasses[key], selectableColumns[key] ? 'is-selectable' : '']"
@click="selectCell($event.currentTarget, key)"
:row="row">
</component>
:class="cellLimitClasses[key]">{{formattedRow[key]}}</td>
</tr>
</template>
<style>
.noselect {
-webkit-touch-callout: none; /* iOS Safari */
-webkit-user-select: none; /* Safari */
-khtml-user-select: none; /* Konqueror HTML */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently
supported by Chrome and Opera */
}
</style>
<script>
import TableCell from './table-cell.vue';
export default {
data: function () {
return {
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
formattedRow: this.row.getFormattedDatum(this.headers),
rowClass: this.row.getRowClass(),
cellLimitClasses: this.row.getCellLimitClasses(),
componentList: Object.keys(this.headers).reduce((components, header) => {
components[header] = this.row.getCellComponentName(header) || 'table-cell';
return components
}, {}),
selectableColumns : Object.keys(this.row.columns).reduce((selectable, columnKeys) => {
selectable[columnKeys] = this.row.columns[columnKeys].selectable;
return selectable;
}, {})
rowLimitClass: this.row.getRowLimitClass(),
cellLimitClasses: this.row.getCellLimitClasses()
}
},
props: {
@@ -99,11 +69,6 @@ export default {
type: Number,
required: false,
default: 0
},
marked: {
type: Boolean,
required: false,
default: false
}
},
methods: {
@@ -112,44 +77,8 @@ export default {
},
formatRow: function (row) {
this.formattedRow = row.getFormattedDatum(this.headers);
this.rowClass = row.getRowClass();
this.rowLimitClass = row.getRowLimitClass();
this.cellLimitClasses = row.getCellLimitClasses();
},
markRow: function (event) {
let keyCtrlModifier = false;
if (event.ctrlKey || event.metaKey) {
keyCtrlModifier = true;
}
if (event.shiftKey) {
this.$emit('markMultipleConcurrent', this.rowIndex);
} else {
if (this.marked) {
this.$emit('unmark', this.rowIndex, keyCtrlModifier);
} else {
this.$emit('mark', this.rowIndex, keyCtrlModifier);
}
}
},
selectCell(element, columnKey) {
if (this.selectableColumns[columnKey]) {
//TODO: This is a hack. Cannot get parent this way.
this.openmct.selection.select([{
element: element,
context: {
type: 'table-cell',
row: this.row.objectKeyString,
column: columnKey
}
},{
element: this.openmct.layout.$refs.browseObject.$el,
context: {
item: this.openmct.router.path[0]
}
}], false);
event.stopPropagation();
}
}
},
// TODO: use computed properties
@@ -159,9 +88,6 @@ export default {
handler: 'formatRow',
deep: false
}
},
components: {
TableCell
}
}
</script>

View File

@@ -20,134 +20,92 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div class="c-table-wrapper">
<div class="c-table-control-bar c-control-bar">
<div class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
:class="{'loading': loading}">
<div class="c-table__control-bar c-control-bar">
<button class="c-button icon-download labeled"
v-if="allowExport"
v-on:click="exportAllDataAsCSV()"
title="Export This View's Data">
<span class="c-button__label">Export Table Data</span>
v-on:click="exportAsCSV()"
title="Export This View's Data">
<span class="c-button__label">Export As CSV</span>
</button>
<button class="c-button icon-download labeled"
v-if="allowExport"
v-show="markedRows.length"
v-on:click="exportMarkedDataAsCSV()"
title="Export Marked Rows As CSV">
<span class="c-button__label">Export Marked Rows</span>
</button>
<button class="c-button icon-x labeled"
v-show="markedRows.length"
v-on:click="unmarkAllRows()"
title="Unmark All Rows">
<span class="c-button__label">Unmark All Rows</span>
</button>
<div v-if="enableMarking"
class="c-separator">
</div>
<button v-if="enableMarking"
class="c-button icon-pause pause-play labeled"
:class=" paused ? 'icon-play is-paused' : 'icon-pause'"
v-on:click="togglePauseByButton()"
:title="paused ? 'Continue Data Flow' : 'Pause Data Flow'">
<span class="c-button__label">
{{paused ? 'Play' : 'Pause'}}
</span>
</button>
<slot name="buttons"></slot>
</div>
<div class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar"
:class="{
'loading': loading,
'paused' : paused
}">
<div :style="{ 'max-width': widthWithScroll, 'min-width': '150px'}"><slot></slot></div>
<div v-if="isDropTargetActive" class="c-telemetry-table__drop-target" :style="dropTargetStyle"></div>
<!-- Headers table -->
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
<table class="c-table__headers c-telemetry-table__headers">
<thead>
<tr class="c-telemetry-table__headers__labels">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
:headerKey="key"
:headerIndex="headerIndex"
@sort="allowSorting && sortBy(key)"
@resizeColumn="resizeColumn"
@dropTargetOffsetChanged="setDropTargetOffset"
@dropTargetActive="dropTargetActive"
@reorderColumn="reorderColumn"
@resizeColumnEnd="updateConfiguredColumnWidths"
:columnWidth="columnWidths[key]"
:sortOptions="sortOptions"
:isEditing="isEditing"
><span class="c-telemetry-table__headers__label">{{title}}</span>
</table-column-header>
</tr>
<tr class="c-telemetry-table__headers__filter">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
:headerKey="key"
:headerIndex="headerIndex"
@resizeColumn="resizeColumn"
@dropTargetOffsetChanged="setDropTargetOffset"
@dropTargetActive="dropTargetActive"
@reorderColumn="reorderColumn"
@resizeColumnEnd="updateConfiguredColumnWidths"
:columnWidth="columnWidths[key]"
:isEditing="isEditing"
>
<search class="c-table__search"
v-model="filters[key]"
v-on:input="filterChanged(key)"
v-on:clear="clearFilter(key)" />
</table-column-header>
</tr>
</thead>
</table>
</div>
<!-- Content table -->
<div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
<div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
<table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
:style="{ height: totalHeight + 'px'}">
<tbody>
<telemetry-table-row v-for="(row, rowIndex) in visibleRows"
:headers="headers"
:columnWidths="columnWidths"
:rowIndex="rowIndex"
:rowOffset="rowOffset"
:rowHeight="rowHeight"
:row="row"
:marked="row.marked"
@mark="markRow"
@unmark="unmarkRow"
@markMultipleConcurrent="markMultipleConcurrentRows">
</telemetry-table-row>
</tbody>
</table>
</div>
<!-- Sizing table -->
<table class="c-telemetry-table__sizing js-telemetry-table__sizing" :style="sizingTableWidth">
<tr>
<template v-for="(title, key) in headers">
<th :key="key" :style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}">{{title}}</th>
</template>
</tr>
<telemetry-table-row v-for="(sizingRowData, objectKeyString) in sizingRows"
:key="objectKeyString"
:headers="headers"
:columnWidths="configuredColumnWidths"
:row="sizingRowData">
</telemetry-table-row>
<div v-if="isDropTargetActive" class="c-telemetry-table__drop-target" :style="dropTargetStyle"></div>
<!-- Headers table -->
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
<table class="c-table__headers c-telemetry-table__headers">
<thead>
<tr class="c-telemetry-table__headers__labels">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
:headerKey="key"
:headerIndex="headerIndex"
@sort="sortBy(key)"
@resizeColumn="resizeColumn"
@dropTargetOffsetChanged="setDropTargetOffset"
@dropTargetActive="dropTargetActive"
@reorderColumn="reorderColumn"
@resizeColumnEnd="updateConfiguredColumnWidths"
:columnWidth="columnWidths[key]"
:sortOptions="sortOptions"
:isEditing="isEditing"
><span class="c-telemetry-table__headers__label">{{title}}</span>
</table-column-header>
</tr>
<tr class="c-telemetry-table__headers__filter">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
:headerKey="key"
:headerIndex="headerIndex"
@resizeColumn="resizeColumn"
@dropTargetOffsetChanged="setDropTargetOffset"
@dropTargetActive="dropTargetActive"
@reorderColumn="reorderColumn"
@resizeColumnEnd="updateConfiguredColumnWidths"
:columnWidth="columnWidths[key]"
:isEditing="isEditing"
>
<search class="c-table__search"
v-model="filters[key]"
v-on:input="filterChanged(key)"
v-on:clear="clearFilter(key)" />
</table-column-header>
</tr>
</thead>
</table>
<telemetry-filter-indicator></telemetry-filter-indicator>
</div>
</div><!-- closes c-table-wrapper -->
<!-- Content table -->
<div class="c-table__body-w c-telemetry-table__body-w js-telemetry-table__body-w" @scroll="scroll" :style="{ 'max-width': widthWithScroll}">
<div class="c-telemetry-table__scroll-forcer" :style="{ width: totalWidth + 'px' }"></div>
<table class="c-table__body c-telemetry-table__body js-telemetry-table__content"
:style="{ height: totalHeight + 'px'}">
<tbody>
<telemetry-table-row v-for="(row, rowIndex) in visibleRows"
:headers="headers"
:columnWidths="columnWidths"
:rowIndex="rowIndex"
:rowOffset="rowOffset"
:rowHeight="rowHeight"
:row="row">
</telemetry-table-row>
</tbody>
</table>
</div>
<!-- Sizing table -->
<table class="c-telemetry-table__sizing js-telemetry-table__sizing" :style="sizingTableWidth">
<tr>
<template v-for="(title, key) in headers">
<th :key="key" :style="{ width: configuredColumnWidths[key] + 'px', 'max-width': configuredColumnWidths[key] + 'px'}">{{title}}</th>
</template>
</tr>
<telemetry-table-row v-for="(sizingRowData, objectKeyString) in sizingRows"
:headers="headers"
:columnWidths="configuredColumnWidths"
:row="sizingRowData">
</telemetry-table-row>
</table>
</div>
</template>
<style lang="scss">
@@ -173,7 +131,7 @@
display: block;
flex: 1 0 auto;
width: 100px;
vertical-align: middle; // This is crucial to hiding 4px height injected by browser by default
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
}
td {
@@ -258,10 +216,6 @@
align-items: stretch;
position: absolute;
height: 18px; // Needed when a row has empty values in its cells
&.is-selected {
background-color: $colorSelectedBg;
}
}
td {
@@ -312,10 +266,6 @@
}
}
.paused {
border: 1px solid #ff9900;
}
/******************************* LEGACY */
.s-status-taking-snapshot,
.overlay.snapshot {
@@ -329,8 +279,6 @@
import TelemetryTableRow from './table-row.vue';
import search from '../../../ui/components/search.vue';
import TableColumnHeader from './table-column-header.vue';
import TelemetryFilterIndicator from './TelemetryFilterIndicator.vue';
import CSVExporter from '../../../exporters/CSVExporter.js';
import _ from 'lodash';
const VISIBLE_ROW_COUNT = 100;
@@ -345,30 +293,13 @@ export default {
components: {
TelemetryTableRow,
TableColumnHeader,
search,
TelemetryFilterIndicator
search
},
inject: ['table', 'openmct'],
inject: ['table', 'openmct', 'csvExporter'],
props: {
isEditing: {
type: Boolean,
default: false
},
allowExport: {
type: Boolean,
default: true
},
allowFiltering: {
'type': Boolean,
'default': true
},
allowSorting: {
'type': Boolean,
'default': true
},
enableMarking: {
type: Boolean,
default: false
}
},
data() {
@@ -397,10 +328,7 @@ export default {
dropOffsetLeft: undefined,
isDropTargetActive: false,
isAutosizeEnabled: configuration.autosize,
scrollW: 0,
markCounter: 0,
paused: false,
markedRows: []
scrollW: 0
}
},
computed: {
@@ -586,27 +514,15 @@ export default {
// which causes subsequent scroll to use an out of date height.
this.contentTable.style.height = this.totalHeight + 'px';
},
exportAsCSV(data) {
exportAsCSV() {
const headerKeys = Object.keys(this.headers);
this.csvExporter.export(data, {
const justTheData = this.table.filteredRows.getRows()
.map(row => row.getFormattedDatum(this.headers));
this.csvExporter.export(justTheData, {
filename: this.table.domainObject.name + '.csv',
headers: headerKeys
});
},
exportAllDataAsCSV() {
const justTheData = this.table.filteredRows.getRows()
.map(row => row.getFormattedDatum(this.headers));
this.exportAsCSV(justTheData);
},
exportMarkedDataAsCSV() {
const data = this.table.filteredRows.getRows()
.filter(row => row.marked === true)
.map(row => row.getFormattedDatum(this.headers));
this.exportAsCSV(data);
},
outstandingRequests(loading) {
this.loading = loading;
},
@@ -695,114 +611,12 @@ export default {
scrollTop = this.scrollable.scrollTop;
}, RESIZE_POLL_INTERVAL);
},
clearRowsAndRerender() {
this.visibleRows = [];
this.$nextTick().then(this.updateVisibleRows);
},
pause(pausedByButton) {
if (pausedByButton) {
this.pausedByButton = true;
}
this.paused = true;
this.table.pause();
},
unpause(unpausedByButton) {
if (unpausedByButton) {
this.paused = false;
this.table.unpause();
this.markedRows = [];
this.pausedByButton = false;
} else {
if (!this.pausedByButton) {
this.paused = false;
this.table.unpause();
this.markedRows = [];
}
}
},
togglePauseByButton() {
if (this.paused) {
this.unpause(true);
} else {
this.pause(true);
}
},
undoMarkedRows(unpause) {
this.markedRows.forEach(r => r.marked = false);
this.markedRows = [];
},
unmarkRow(rowIndex) {
this.undoMarkedRows();
this.unpause();
},
markRow(rowIndex, keyModifier) {
if (!this.enableMarking) {
return;
}
let insertMethod = 'unshift';
if (this.markedRows.length && !keyModifier) {
this.undoMarkedRows();
insertMethod = 'push';
}
let markedRow = this.visibleRows[rowIndex];
this.$set(markedRow, 'marked', true);
this.pause();
this.markedRows[insertMethod](markedRow);
},
unmarkAllRows(skipUnpause) {
this.markedRows.forEach(row => row.marked = false);
this.markedRows = [];
this.unpause();
},
markMultipleConcurrentRows(rowIndex) {
if (!this.enableMarking) {
return;
}
if (!this.markedRows.length) {
this.markRow(rowIndex);
} else {
if (this.markedRows.length > 1) {
this.markedRows.forEach((r,i) => {
if (i !== 0) {
r.marked = false;
}
});
this.markedRows.splice(1);
}
let lastRowToBeMarked = this.visibleRows[rowIndex];
let allRows = this.table.filteredRows.getRows(),
firstRowIndex = allRows.indexOf(this.markedRows[0]),
lastRowIndex = allRows.indexOf(lastRowToBeMarked);
//supports backward selection
if (lastRowIndex < firstRowIndex) {
let temp = lastRowIndex;
lastRowIndex = firstRowIndex;
firstRowIndex = temp - 1;
}
for (var i = firstRowIndex + 1; i <= lastRowIndex; i++) {
let row = allRows[i];
row.marked = true;
this.markedRows.push(row);
}
}
}
},
created() {
this.filterChanged = _.debounce(this.filterChanged, 500);
},
mounted() {
this.csvExporter = new CSVExporter();
this.rowsAdded = _.throttle(this.rowsAdded, 200);
this.rowsRemoved = _.throttle(this.rowsRemoved, 200);
this.scroll = _.throttle(this.scroll, 100);
@@ -810,7 +624,6 @@ export default {
this.table.on('object-added', this.addObject);
this.table.on('object-removed', this.removeObject);
this.table.on('outstanding-requests', this.outstandingRequests);
this.table.on('refresh', this.clearRowsAndRerender);
this.table.filteredRows.on('add', this.rowsAdded);
this.table.filteredRows.on('remove', this.rowsRemoved);
@@ -836,7 +649,6 @@ export default {
this.table.off('object-added', this.addObject);
this.table.off('object-removed', this.removeObject);
this.table.off('outstanding-requests', this.outstandingRequests);
this.table.off('refresh', this.clearRowsAndRerender);
this.table.filteredRows.off('add', this.rowsAdded);
this.table.filteredRows.off('remove', this.rowsRemoved);

View File

@@ -0,0 +1,6 @@
<tr :style="{ top: rowTop }" :class="rowLimitClass">
<td v-for="(title, key, headerIndex) in headers"
:style="{ width: columnWidths[headerIndex], 'max-width': columnWidths[headerIndex]}"
:title="formattedRow[key]"
:class="cellLimitClasses[key]">{{formattedRow[key]}}</td>
</tr>

View File

@@ -70,6 +70,9 @@ $colorBodyFgEm: #fff;
$colorGenBg: #222;
$colorHeadBg: #262626;
$colorHeadFg: $colorBodyFg;
$colorStatusBarBg: $colorHeadBg;
$colorStatusBarFg: $colorBodyFg;
$colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #26d8ff;
@@ -98,12 +101,10 @@ $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?
$colorStatusPartialBg: #3f5e8b;
$colorStatusCompleteBg: #457638;
$colorAlert: #ff3c00;
$colorAlertFg: #fff;
$colorWarningHi: #ff0000;
$colorWarningHiFg: #ffdad0;
$colorWarningHi: #990000;
$colorWarningHiFg: #FF9594;
$colorWarningLo: #ff9900;
$colorWarningLoFg: #523400;
$colorDiagnostic: #a4b442;
@@ -114,8 +115,6 @@ $colorInfo: #2294a2;
$colorInfoFg: #fff;
$colorOk: #33cc33;
$colorOkFg: #fff;
$colorFilterBg: #44449c;
$colorFilterFg: #8984e9;
// States
$colorPausedBg: #ff9900;
@@ -278,11 +277,6 @@ $colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #555555;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #777777;
$colorIndicatorBgHov: rgba($colorHeadFg, 0.1);
$colorIndicatorMenuBg: $colorHeadBg;
$colorIndicatorMenuBgShdw: rgba(white, 0.6) 0 0 6px;
$colorIndicatorMenuFg: $colorHeadFg;
$colorIndicatorMenuFgHov: pullForward($colorHeadFg, 10%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);

View File

@@ -74,6 +74,9 @@ $colorBodyFgEm: #fff;
$colorGenBg: #222;
$colorHeadBg: #262626;
$colorHeadFg: $colorBodyFg;
$colorStatusBarBg: $colorHeadBg;
$colorStatusBarFg: $colorBodyFg;
$colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #26d8ff;
@@ -102,12 +105,10 @@ $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?
$colorStatusPartialBg: #3f5e8b;
$colorStatusCompleteBg: #457638;
$colorAlert: #ff3c00;
$colorAlertFg: #fff;
$colorWarningHi: #ff0000;
$colorWarningHiFg: #ffdad0;
$colorWarningHi: #990000;
$colorWarningHiFg: #FF9594;
$colorWarningLo: #ff9900;
$colorWarningLoFg: #523400;
$colorDiagnostic: #a4b442;
@@ -118,8 +119,6 @@ $colorInfo: #2294a2;
$colorInfoFg: #fff;
$colorOk: #33cc33;
$colorOkFg: #fff;
$colorFilterBg: #44449c;
$colorFilterFg: #8984e9;
// States
$colorPausedBg: #ff9900;
@@ -282,11 +281,6 @@ $colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #555555;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #777777;
$colorIndicatorBgHov: rgba($colorHeadFg, 0.1);
$colorIndicatorMenuBg: $colorHeadBg;
$colorIndicatorMenuBgShdw: rgba(white, 0.6) 0 0 6px;
$colorIndicatorMenuFg: $colorHeadFg;
$colorIndicatorMenuFgHov: pullForward($colorHeadFg, 10%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);

View File

@@ -70,6 +70,9 @@ $colorBodyFgEm: #333;
$colorGenBg: #fff;
$colorHeadBg: #eee;
$colorHeadFg: $colorBodyFg;
$colorStatusBarBg: #000;
$colorStatusBarFg: #999;
$colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #00c0f6;
@@ -98,8 +101,6 @@ $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?
$colorStatusPartialBg: #c9d6ff;
$colorStatusCompleteBg: #a4e4b4;
$colorAlert: #ff3c00;
$colorAlertFg: #fff;
$colorWarningHi: #990000;
@@ -114,8 +115,6 @@ $colorInfo: #2294a2;
$colorInfoFg: #fff;
$colorOk: #33cc33;
$colorOkFg: #fff;
$colorFilterBg: #a29fe2;
$colorFilterFg: #fff;
// States
$colorPausedBg: #ff9900;
@@ -278,11 +277,6 @@ $colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #444;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #666;
$colorIndicatorBgHov: rgba($colorHeadFg, 0.1);
$colorIndicatorMenuBg: white;
$colorIndicatorMenuBgShdw: rgba(black, 0.6) 0 0 6px;
$colorIndicatorMenuFg: $colorHeadFg;
$colorIndicatorMenuFgHov: pullForward($colorHeadFg, 10%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);

View File

@@ -141,8 +141,6 @@ $glyph-icon-grid: '\e922';
$glyph-icon-grippy-ew: '\e923';
$glyph-icon-columns: '\e924';
$glyph-icon-rows: '\e925';
$glyph-icon-filter: '\e926';
$glyph-icon-filter-outline: '\e927';
$glyph-icon-arrows-right-left: '\ea00';
$glyph-icon-arrows-up-down: '\ea01';
$glyph-icon-bullet: '\ea02';

View File

@@ -75,17 +75,11 @@ button {
}
}
/********* Icon Buttons and Links */
/********* Icon Buttons */
.c-click-icon {
@include cClickIcon();
}
.c-click-link {
// A clickable element, typically inline, with an icon and label
@include cControl();
cursor: pointer;
}
.c-icon-button,
.c-click-swatch {
@include cClickIconButton();
@@ -600,15 +594,15 @@ select {
margin-right: $m;
}
.c-separator {
@include cToolbarSeparator();
}
.c-toolbar {
> * + * {
margin-left: 2px;
}
&__button {
}
&__separator {
@include cToolbarSeparator();
}

View File

@@ -30,10 +30,10 @@
}
@font-face {
// Use https://icomoon.io/app with icomoon-project-Open-MCT-Symbols-12px.json to generate font files
// Use https://icomoon.io/app with icomoon-project-openmct-symbols-12px.json to generate font files
font-family: 'symbolsfont-12px';
src: url('./fonts/Open-MCT-Symbols-12px.woff') format('woff'),
url('./fonts/Open-MCT-Symbols-12px.ttf') format('truetype');
src: url('./fonts/openmct-symbols-12px.woff') format('woff'),
url('./fonts/openmct-symbols-12px.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@@ -77,8 +77,6 @@
.icon-grippy-ew { @include glyphBefore($glyph-icon-grippy-ew); }
.icon-columns { @include glyphBefore($glyph-icon-columns); }
.icon-rows { @include glyphBefore($glyph-icon-rows); }
.icon-filter { @include glyphBefore($glyph-icon-filter); }
.icon-filter-outline { @include glyphBefore($glyph-icon-filter-outline); }
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }
.icon-bullet { @include glyphBefore($glyph-icon-bullet); }
@@ -166,8 +164,6 @@
/************************** 12 PX CLASSES */
// TODO: sync with 16px redo as of 10/25/18
.icon-filter-12px { @include glyphBefore($glyph-icon-filter,'symbolsfont-12px'); }
.icon-filter-outline-12px { @include glyphBefore($glyph-icon-filter-outline,'symbolsfont-12px'); }
.icon-crosshair-12px { @include glyphBefore($glyph-icon-crosshair,'symbolsfont-12px'); }
.icon-folder-12px { @include glyphBefore($glyph-icon-folder,'symbolsfont-12px'); }
.icon-list-view-12px { @include glyphBefore($glyph-icon-list-view,'symbolsfont-12px'); }

View File

@@ -782,6 +782,133 @@ mct-indicators mct-include {
display: contents;
}
/*
// MOVED TO INDICATORS.VUE
.ls-indicator {
$bg: rgba(white, 0.2) !important;
$hbg: $colorStatusBarBg;
$hshdw: rgba(white, 0.4) 0 0 3px;
$br: $controlCr;
$hoverYOffset: -35px;
background: transparent !important;
border-radius: $br;
display: inline-block;
position: relative;
padding: 1px $interiorMarginSm; // Use padding instead of margin to keep hover chatter to a minimum
text-transform: uppercase;
&:before {
display: inline-block;
}
.label {
// Hover bubbles that appear when hovering on an Indicator
display: inline-block;
a,
button,
s-button,
.c-button {
// Make <a> in label look like buttons
transition: $transIn;
background: transparent;
border: 1px solid rgba($colorStatusBarFg, 0.5);
border-radius: $br;
box-sizing: border-box;
color: inherit;
font-size: inherit;
height: auto;
line-height: normal;
padding: 0 2px;
&:hover {
background: $bg;
color: #fff;
}
}
[class*='icon-'] {
// If any elements within label include the class 'icon-*' then deal with their :before's
&:before {
font-size: 0.8em;
margin-right: $interiorMarginSm;
}
}
}
&.no-collapse {
display: flex;
flex-flow: row nowrap;
align-items: center;
> *,
&:before {
flex: 1 1 auto;
}
&:before {
margin-right: $interiorMarginSm;
}
}
&:not(.no-collapse) {
&:before {
margin-right: 0 !important;
}
.label {
transition: all 250ms ease-in 100ms;
background: $hbg;
border-radius: $br;
font-size: .6rem;
left: 0;
top: 140%;
opacity: 0;
padding: $interiorMarginSm $interiorMargin;
position: absolute;
transform-origin: 10px 100%;
transform: scale(0.0);
white-space: nowrap;
z-index: 50;
&:before {
// Infobubble-style arrow element
content: '';
display: block;
position: absolute;
bottom: 100%;
@include triangle('up', $size: 4px, $ratio: 1, $color: $hbg);
}
}
@include hover() {
background: $bg;
.label {
opacity: 1;
transform: scale(1.0);
transition: all 100ms ease-out 0s;
}
}
}
&.float-right {
float: right;
}
}
// Hide the clock indicator when we're phone portrait
body.phone.portrait {
.ls-indicator.t-indicator-clock {
display: none;
}
}
*/
/************************************************* DATETIME UI */
@mixin complexFieldHolder($myW) {
width: $myW + $interiorMargin;

View File

@@ -61,7 +61,7 @@
}
@mixin indicatorStatusColors($c) {
&:before, .c-indicator__count {
&:before, .count {
color: $c;
}
}
@@ -159,16 +159,3 @@ tr {
@include indicatorStatusColors($colorStatusError);
}
}
.s-status {
&--partial {
// Partially completed things, such as a file downloading or process that's running
background-color: $colorStatusPartialBg;
}
&--complete {
// Completed things, such as a file downloaded or process that's finished
background-color: $colorStatusCompleteBg;
}
}

View File

@@ -76,43 +76,23 @@ div.c-table {
height: 100%;
}
.c-table-wrapper {
// Wraps .c-control-bar and .c-table
@include abs();
overflow: hidden;
display: flex;
flex-direction: column;
> .c-table {
height: auto;
flex: 1 1 auto;
}
> * + * {
margin-top: $interiorMarginSm;
}
}
.c-table-control-bar {
display: flex;
flex: 0 0 auto;
> * + * {
margin-left: $interiorMarginSm;
}
}
.c-table {
// Can be used by any type of table, scrolling, LAD, etc.
$min-w: 50px;
width: 100%;
&__control-bar,
&__headers-w {
flex: 0 0 auto;
}
/******************************* ELEMENTS */
&__control-bar {
margin-bottom: $interiorMarginSm;
}
thead tr,
&.c-table__headers {
background: $colorTabHeaderBg;

View File

@@ -1,8 +1,8 @@
{
"metadata": {
"name": "Open MCT Symbols 16px",
"name": "Open MCT Symbols",
"lastOpened": 0,
"created": 1561482854927
"created": 1541830438012
},
"iconSets": [
{
@@ -317,29 +317,13 @@
"code": 59685,
"tempChar": ""
},
{
"order": 161,
"id": 142,
"name": "icon-filter",
"prevSize": 32,
"code": 59686,
"tempChar": ""
},
{
"order": 162,
"id": 141,
"name": "icon-filter-outline",
"prevSize": 32,
"code": 59687,
"tempChar": ""
},
{
"order": 27,
"id": 105,
"name": "icon-arrows-right-left",
"prevSize": 32,
"code": 59904,
"tempChar": ""
"tempChar": ""
},
{
"order": 26,
@@ -347,7 +331,7 @@
"name": "icon-arrows-up-down",
"prevSize": 32,
"code": 59905,
"tempChar": ""
"tempChar": ""
},
{
"order": 68,
@@ -355,7 +339,7 @@
"name": "icon-bullet",
"prevSize": 32,
"code": 59906,
"tempChar": ""
"tempChar": ""
},
{
"order": 150,
@@ -363,7 +347,7 @@
"prevSize": 32,
"code": 59907,
"name": "icon-calendar",
"tempChar": ""
"tempChar": ""
},
{
"order": 45,
@@ -371,7 +355,7 @@
"name": "icon-chain-links",
"prevSize": 32,
"code": 59908,
"tempChar": ""
"tempChar": ""
},
{
"order": 73,
@@ -379,7 +363,7 @@
"name": "icon-download",
"prevSize": 32,
"code": 59909,
"tempChar": ""
"tempChar": ""
},
{
"order": 39,
@@ -387,7 +371,7 @@
"name": "icon-duplicate",
"prevSize": 32,
"code": 59910,
"tempChar": ""
"tempChar": ""
},
{
"order": 50,
@@ -395,7 +379,7 @@
"name": "icon-folder-new",
"prevSize": 32,
"code": 59911,
"tempChar": ""
"tempChar": ""
},
{
"order": 138,
@@ -403,7 +387,7 @@
"name": "icon-fullscreen-collapse",
"prevSize": 32,
"code": 59912,
"tempChar": ""
"tempChar": ""
},
{
"order": 139,
@@ -411,7 +395,7 @@
"name": "icon-fullscreen-expand",
"prevSize": 32,
"code": 59913,
"tempChar": ""
"tempChar": ""
},
{
"order": 122,
@@ -419,7 +403,7 @@
"name": "icon-layers",
"prevSize": 32,
"code": 59914,
"tempChar": ""
"tempChar": ""
},
{
"order": 151,
@@ -427,7 +411,7 @@
"name": "icon-line-horz",
"prevSize": 32,
"code": 59915,
"tempChar": ""
"tempChar": ""
},
{
"order": 100,
@@ -435,7 +419,7 @@
"name": "icon-magnify",
"prevSize": 32,
"code": 59916,
"tempChar": ""
"tempChar": ""
},
{
"order": 99,
@@ -443,7 +427,7 @@
"name": "icon-magnify-in",
"prevSize": 32,
"code": 59917,
"tempChar": ""
"tempChar": ""
},
{
"order": 101,
@@ -451,7 +435,7 @@
"name": "icon-magnify-out-v2",
"prevSize": 32,
"code": 59918,
"tempChar": ""
"tempChar": ""
},
{
"order": 103,
@@ -459,7 +443,7 @@
"name": "icon-menu",
"prevSize": 32,
"code": 59919,
"tempChar": ""
"tempChar": ""
},
{
"order": 124,
@@ -467,7 +451,7 @@
"name": "icon-move",
"prevSize": 32,
"code": 59920,
"tempChar": ""
"tempChar": ""
},
{
"order": 7,
@@ -475,7 +459,7 @@
"name": "icon-new-window",
"prevSize": 32,
"code": 59921,
"tempChar": ""
"tempChar": ""
},
{
"order": 63,
@@ -483,7 +467,7 @@
"name": "icon-paint-bucket-v2",
"prevSize": 32,
"code": 59922,
"tempChar": ""
"tempChar": ""
},
{
"order": 15,
@@ -491,7 +475,7 @@
"name": "icon-pencil",
"prevSize": 32,
"code": 59923,
"tempChar": ""
"tempChar": ""
},
{
"order": 54,
@@ -499,7 +483,7 @@
"name": "icon-pencil-edit-in-place",
"prevSize": 32,
"code": 59924,
"tempChar": ""
"tempChar": ""
},
{
"order": 40,
@@ -507,7 +491,7 @@
"name": "icon-play",
"prevSize": 32,
"code": 59925,
"tempChar": ""
"tempChar": ""
},
{
"order": 125,
@@ -515,7 +499,7 @@
"name": "icon-pause",
"prevSize": 32,
"code": 59926,
"tempChar": ""
"tempChar": ""
},
{
"order": 119,
@@ -523,7 +507,7 @@
"name": "icon-plot-resource",
"prevSize": 32,
"code": 59927,
"tempChar": ""
"tempChar": ""
},
{
"order": 48,
@@ -531,7 +515,7 @@
"name": "icon-pointer-left",
"prevSize": 32,
"code": 59928,
"tempChar": ""
"tempChar": ""
},
{
"order": 47,
@@ -539,7 +523,7 @@
"name": "icon-pointer-right",
"prevSize": 32,
"code": 59929,
"tempChar": ""
"tempChar": ""
},
{
"order": 85,
@@ -547,7 +531,7 @@
"name": "icon-refresh",
"prevSize": 32,
"code": 59930,
"tempChar": ""
"tempChar": ""
},
{
"order": 55,
@@ -555,7 +539,7 @@
"name": "icon-save",
"prevSize": 32,
"code": 59931,
"tempChar": ""
"tempChar": ""
},
{
"order": 56,
@@ -563,7 +547,7 @@
"name": "icon-save-as",
"prevSize": 32,
"code": 59932,
"tempChar": ""
"tempChar": ""
},
{
"order": 58,
@@ -571,7 +555,7 @@
"name": "icon-sine",
"prevSize": 32,
"code": 59933,
"tempChar": ""
"tempChar": ""
},
{
"order": 113,
@@ -579,7 +563,7 @@
"name": "icon-font",
"prevSize": 32,
"code": 59934,
"tempChar": ""
"tempChar": ""
},
{
"order": 41,
@@ -587,7 +571,7 @@
"name": "icon-thumbs-strip",
"prevSize": 32,
"code": 59935,
"tempChar": ""
"tempChar": ""
},
{
"order": 146,
@@ -595,7 +579,7 @@
"name": "icon-two-parts-both",
"prevSize": 32,
"code": 59936,
"tempChar": ""
"tempChar": ""
},
{
"order": 145,
@@ -603,7 +587,7 @@
"name": "icon-two-parts-one-only",
"prevSize": 32,
"code": 59937,
"tempChar": ""
"tempChar": ""
},
{
"order": 82,
@@ -611,7 +595,7 @@
"name": "icon-resync",
"prevSize": 32,
"code": 59938,
"tempChar": ""
"tempChar": ""
},
{
"order": 86,
@@ -619,7 +603,7 @@
"name": "icon-reset",
"prevSize": 32,
"code": 59939,
"tempChar": ""
"tempChar": ""
},
{
"order": 61,
@@ -627,7 +611,7 @@
"name": "icon-x-in-circle",
"prevSize": 32,
"code": 59940,
"tempChar": ""
"tempChar": ""
},
{
"order": 84,
@@ -635,7 +619,7 @@
"name": "icon-brightness",
"prevSize": 32,
"code": 59941,
"tempChar": ""
"tempChar": ""
},
{
"order": 83,
@@ -643,7 +627,7 @@
"name": "icon-contrast",
"prevSize": 32,
"code": 59942,
"tempChar": ""
"tempChar": ""
},
{
"order": 87,
@@ -651,7 +635,7 @@
"name": "icon-expand",
"prevSize": 32,
"code": 59943,
"tempChar": ""
"tempChar": ""
},
{
"order": 89,
@@ -659,7 +643,7 @@
"name": "icon-list-view",
"prevSize": 32,
"code": 59944,
"tempChar": ""
"tempChar": ""
},
{
"order": 133,
@@ -667,7 +651,7 @@
"name": "icon-grid-snap-to",
"prevSize": 32,
"code": 59945,
"tempChar": ""
"tempChar": ""
},
{
"order": 132,
@@ -675,7 +659,7 @@
"name": "icon-grid-snap-no",
"prevSize": 32,
"code": 59946,
"tempChar": ""
"tempChar": ""
},
{
"order": 94,
@@ -683,7 +667,7 @@
"name": "icon-frame-show",
"prevSize": 32,
"code": 59947,
"tempChar": ""
"tempChar": ""
},
{
"order": 95,
@@ -691,7 +675,7 @@
"name": "icon-frame-hide",
"prevSize": 32,
"code": 59948,
"tempChar": ""
"tempChar": ""
},
{
"order": 97,
@@ -699,7 +683,7 @@
"name": "icon-import",
"prevSize": 32,
"code": 59949,
"tempChar": ""
"tempChar": ""
},
{
"order": 96,
@@ -707,7 +691,7 @@
"name": "icon-export",
"prevSize": 32,
"code": 59950,
"tempChar": ""
"tempChar": ""
},
{
"order": 114,
@@ -715,7 +699,7 @@
"name": "icon-font-size",
"prevSize": 32,
"code": 59951,
"tempChar": ""
"tempChar": ""
},
{
"order": 144,
@@ -723,7 +707,7 @@
"name": "icon-activity",
"prevSize": 32,
"code": 60160,
"tempChar": ""
"tempChar": ""
},
{
"order": 104,
@@ -731,7 +715,7 @@
"name": "icon-activity-mode",
"prevSize": 32,
"code": 60161,
"tempChar": ""
"tempChar": ""
},
{
"order": 137,
@@ -739,7 +723,7 @@
"name": "icon-autoflow-tabular",
"prevSize": 32,
"code": 60162,
"tempChar": ""
"tempChar": ""
},
{
"order": 115,
@@ -747,7 +731,7 @@
"name": "icon-clock",
"prevSize": 32,
"code": 60163,
"tempChar": ""
"tempChar": ""
},
{
"order": 2,
@@ -755,7 +739,7 @@
"name": "icon-database",
"prevSize": 32,
"code": 60164,
"tempChar": ""
"tempChar": ""
},
{
"order": 3,
@@ -763,7 +747,7 @@
"name": "icon-database-query",
"prevSize": 32,
"code": 60165,
"tempChar": ""
"tempChar": ""
},
{
"order": 67,
@@ -771,7 +755,7 @@
"name": "icon-dataset",
"prevSize": 32,
"code": 60166,
"tempChar": ""
"tempChar": ""
},
{
"order": 59,
@@ -779,7 +763,7 @@
"name": "icon-datatable",
"prevSize": 32,
"code": 60167,
"tempChar": ""
"tempChar": ""
},
{
"order": 136,
@@ -787,7 +771,7 @@
"name": "icon-dictionary",
"prevSize": 32,
"code": 60168,
"tempChar": ""
"tempChar": ""
},
{
"order": 51,
@@ -795,7 +779,7 @@
"name": "icon-folder",
"prevSize": 32,
"code": 60169,
"tempChar": ""
"tempChar": ""
},
{
"order": 147,
@@ -803,7 +787,7 @@
"name": "icon-image",
"prevSize": 32,
"code": 60170,
"tempChar": ""
"tempChar": ""
},
{
"order": 4,
@@ -811,7 +795,7 @@
"name": "icon-layout",
"prevSize": 32,
"code": 60171,
"tempChar": ""
"tempChar": ""
},
{
"order": 24,
@@ -819,7 +803,7 @@
"name": "icon-object",
"prevSize": 32,
"code": 60172,
"tempChar": ""
"tempChar": ""
},
{
"order": 52,
@@ -827,7 +811,7 @@
"name": "icon-object-unknown",
"prevSize": 32,
"code": 60173,
"tempChar": ""
"tempChar": ""
},
{
"order": 105,
@@ -835,7 +819,7 @@
"name": "icon-packet",
"prevSize": 32,
"code": 60174,
"tempChar": ""
"tempChar": ""
},
{
"order": 126,
@@ -843,7 +827,7 @@
"name": "icon-page",
"prevSize": 32,
"code": 60175,
"tempChar": ""
"tempChar": ""
},
{
"order": 130,
@@ -851,7 +835,7 @@
"name": "icon-plot-overlay",
"prevSize": 32,
"code": 60176,
"tempChar": ""
"tempChar": ""
},
{
"order": 80,
@@ -859,7 +843,7 @@
"name": "icon-plot-stacked",
"prevSize": 32,
"code": 60177,
"tempChar": ""
"tempChar": ""
},
{
"order": 134,
@@ -867,7 +851,7 @@
"name": "icon-session",
"prevSize": 32,
"code": 60178,
"tempChar": ""
"tempChar": ""
},
{
"order": 109,
@@ -875,7 +859,7 @@
"name": "icon-tabular",
"prevSize": 32,
"code": 60179,
"tempChar": ""
"tempChar": ""
},
{
"order": 107,
@@ -883,7 +867,7 @@
"name": "icon-tabular-lad",
"prevSize": 32,
"code": 60180,
"tempChar": ""
"tempChar": ""
},
{
"order": 106,
@@ -891,7 +875,7 @@
"name": "icon-tabular-lad-set",
"prevSize": 32,
"code": 60181,
"tempChar": ""
"tempChar": ""
},
{
"order": 70,
@@ -899,7 +883,7 @@
"name": "icon-tabular-realtime",
"prevSize": 32,
"code": 60182,
"tempChar": ""
"tempChar": ""
},
{
"order": 60,
@@ -907,7 +891,7 @@
"name": "icon-tabular-scrolling",
"prevSize": 32,
"code": 60183,
"tempChar": ""
"tempChar": ""
},
{
"order": 131,
@@ -915,7 +899,7 @@
"name": "icon-telemetry",
"prevSize": 32,
"code": 60184,
"tempChar": ""
"tempChar": ""
},
{
"order": 108,
@@ -923,7 +907,7 @@
"name": "icon-timeline",
"prevSize": 32,
"code": 60185,
"tempChar": ""
"tempChar": ""
},
{
"order": 81,
@@ -931,7 +915,7 @@
"name": "icon-timer",
"prevSize": 32,
"code": 60186,
"tempChar": ""
"tempChar": ""
},
{
"order": 69,
@@ -939,7 +923,7 @@
"name": "icon-topic",
"prevSize": 32,
"code": 60187,
"tempChar": ""
"tempChar": ""
},
{
"order": 79,
@@ -947,7 +931,7 @@
"name": "icon-box-with-dashed-lines-v2",
"prevSize": 32,
"code": 60188,
"tempChar": ""
"tempChar": ""
},
{
"order": 90,
@@ -955,7 +939,7 @@
"name": "icon-summary-widget",
"prevSize": 32,
"code": 60189,
"tempChar": ""
"tempChar": ""
},
{
"order": 92,
@@ -963,7 +947,7 @@
"name": "icon-notebook",
"prevSize": 32,
"code": 60190,
"tempChar": ""
"tempChar": ""
},
{
"order": 118,
@@ -971,7 +955,7 @@
"name": "icon-tabs-view",
"prevSize": 32,
"code": 60191,
"tempChar": ""
"tempChar": ""
},
{
"order": 117,
@@ -979,7 +963,7 @@
"name": "icon-flexible-layout",
"prevSize": 32,
"code": 60192,
"tempChar": ""
"tempChar": ""
},
{
"order": 152,
@@ -987,7 +971,7 @@
"name": "icon-generator-sine",
"prevSize": 32,
"code": 60193,
"tempChar": ""
"tempChar": ""
},
{
"order": 153,
@@ -995,7 +979,7 @@
"name": "icon-generator-event",
"prevSize": 32,
"code": 60194,
"tempChar": ""
"tempChar": ""
},
{
"order": 160,
@@ -1003,7 +987,7 @@
"name": "icon-gauge",
"prevSize": 32,
"code": 60195,
"tempChar": ""
"tempChar": ""
}
],
"id": 0,
@@ -1618,46 +1602,6 @@
]
}
},
{
"id": 142,
"paths": [
"M896 0h-768c-70.601 0.227-127.773 57.399-128 127.978l-0 0.022v768c0.227 70.601 57.399 127.773 127.978 128l0.022 0h256v-512l-192-192h640l-192 192v512h256c70.601-0.227 127.773-57.399 128-127.978l0-0.022v-768c-0.227-70.601-57.399-127.773-127.978-128l-0.022-0z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 1,
"tags": [
"icon-filter"
],
"colorPermutations": {
"11841841841": [
{}
]
}
},
{
"id": 141,
"paths": [
"M896 0h-768c-70.601 0.227-127.773 57.399-128 127.978l-0 0.022v768c0.227 70.601 57.399 127.773 127.978 128l0.022 0h768c70.601-0.227 127.773-57.399 128-127.978l0-0.022v-768c-0.227-70.601-57.399-127.773-127.978-128l-0.022-0zM896 895.8h-256v-383.8l192-192h-640l192 192v384h-256v-767.8h768z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 1,
"tags": [
"icon-filter-outline"
],
"colorPermutations": {
"11841841841": [
{}
]
}
},
{
"id": 105,
"paths": [

BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.ttf Normal file → Executable file

Binary file not shown.

BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.woff Normal file → Executable file

Binary file not shown.

View File

@@ -1,35 +1,19 @@
{
"metadata": {
"name": "Open MCT Symbols 12px",
"name": "openmct-symbols-12px",
"lastOpened": 0,
"created": 1561483556329
"created": 1527031065005
},
"iconSets": [
{
"selection": [
{
"order": 12,
"id": 10,
"name": "icon12-filter",
"prevSize": 12,
"code": 59686,
"tempChar": ""
},
{
"order": 14,
"id": 11,
"name": "icon12-filter-outline",
"prevSize": 12,
"code": 59687,
"tempChar": ""
},
{
"order": 9,
"id": 6,
"name": "icon12-crosshair",
"prevSize": 12,
"code": 59696,
"tempChar": ""
"tempChar": ""
},
{
"order": 11,
@@ -37,7 +21,7 @@
"name": "icon12-grippy",
"prevSize": 12,
"code": 59697,
"tempChar": ""
"tempChar": ""
},
{
"order": 10,
@@ -45,7 +29,7 @@
"name": "icon12-list-view",
"prevSize": 12,
"code": 921666,
"tempChar": ""
"tempChar": ""
},
{
"order": 6,
@@ -53,14 +37,14 @@
"prevSize": 12,
"code": 921865,
"name": "icon12-folder",
"tempChar": ""
"tempChar": ""
}
],
"id": 0,
"metadata": {
"name": "Open MCT Symbols 12px",
"name": "openmct-symbols-12px",
"importSize": {
"width": 384,
"width": 279,
"height": 384
},
"designer": "Charles Hacskaylo"
@@ -68,28 +52,6 @@
"height": 1024,
"prevSize": 12,
"icons": [
{
"id": 10,
"paths": [
"M853.333 0h-682.667c-94.135 0.302-170.364 76.532-170.667 170.638l-0 0.029v682.667c0.302 94.135 76.532 170.364 170.638 170.667l0.029 0h256v-341.333l-341.333-341.333h853.333l-341.333 341.333 1.067 341.333h254.933c94.135-0.302 170.364-76.532 170.667-170.638l0-0.029v-682.667c-0.302-94.135-76.532-170.364-170.638-170.667l-0.029-0z"
],
"attrs": [],
"grid": 0,
"tags": [
"icon12-filter"
]
},
{
"id": 11,
"paths": [
"M853.333 0h-682.667c-94.135 0.302-170.364 76.532-170.667 170.638l-0 0.029v682.667c0.302 94.135 76.532 170.364 170.638 170.667l0.029 0h682.667c94.135-0.302 170.364-76.532 170.667-170.638l0-0.029v-682.667c-0.302-94.135-76.532-170.364-170.638-170.667l-0.029-0zM170.933 853.333h-0.267v-512l256 256v256zM853.067 853.333h-255.2l-0.533-256 256-256v511.733zM853.333 341.333h-682.667v-170.4h682.667z"
],
"attrs": [],
"grid": 0,
"tags": [
"icon12-filter-outline"
]
},
{
"id": 6,
"paths": [
@@ -98,11 +60,26 @@
"M597.333 768h-170.667v256h170.667v-256z",
"M256 426.667h-256v170.667h256v-170.667z"
],
"attrs": [],
"attrs": [
{},
{},
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"icon12-crosshair"
]
],
"colorPermutations": {
"1161751": [
{},
{},
{},
{}
]
}
},
{
"id": 8,
@@ -118,12 +95,39 @@
"M744.773 511.867c0 51.458-41.715 93.173-93.173 93.173s-93.173-41.715-93.173-93.173c0-51.458 41.715-93.173 93.173-93.173s93.173 41.715 93.173 93.173z",
"M744.773 791.36c0 51.458-41.715 93.173-93.173 93.173s-93.173-41.715-93.173-93.173c0-51.458 41.715-93.173 93.173-93.173s93.173 41.715 93.173 93.173z"
],
"attrs": [],
"attrs": [
{},
{},
{},
{},
{},
{},
{},
{},
{},
{}
],
"width": 745,
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"icon12-grippy"
]
],
"colorPermutations": {
"1161751": [
{},
{},
{},
{},
{},
{},
{},
{},
{},
{}
]
}
},
{
"id": 7,
@@ -132,11 +136,24 @@
"M0 426.667h1024v170.667h-1024v-170.667z",
"M0 853.333h1024v170.667h-1024v-170.667z"
],
"attrs": [],
"attrs": [
{},
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 0,
"tags": [
"icon12-list-view"
]
],
"colorPermutations": {
"1161751": [
{},
{},
{}
]
}
},
{
"id": 3,
@@ -145,14 +162,40 @@
"M85.333 426.667h853.333c47.128 0 85.333 38.205 85.333 85.333v426.667c0 47.128-38.205 85.333-85.333 85.333h-853.333c-47.128 0-85.333-38.205-85.333-85.333v-426.667c0-47.128 38.205-85.333 85.333-85.333z"
],
"attrs": [],
"isMulticolor": false,
"grid": 0,
"tags": [
"icon12-folder"
]
],
"colorPermutations": {
"1161751": [
{
"f": 0
},
{
"f": 0
}
]
}
}
],
"invisible": false,
"colorThemes": [],
"colorThemes": [
[
[
0,
0,
0,
1
],
[
0,
161,
75,
1
]
]
],
"colorThemeIdx": 0
}
],
@@ -163,9 +206,9 @@
"showQuickUse2": true,
"showSVGs": true,
"fontPref": {
"prefix": "openmct-symbols-",
"prefix": "icon-",
"metadata": {
"fontFamily": "Open-MCT-Symbols-12px",
"fontFamily": "openmct-symbols-12px",
"majorVersion": 1,
"minorVersion": 0
},
@@ -174,12 +217,7 @@
"baseline": 6.25,
"whitespace": 50
},
"embed": false,
"noie8": true,
"ie7": false,
"showMetadata": false,
"includeMetadata": false,
"showMetrics": true
"embed": false
},
"imagePref": {
"prefix": "icon-",

Binary file not shown.

Binary file not shown.

View File

@@ -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";

View File

@@ -0,0 +1,22 @@
<template>
<div class="c-indicator no-collapse icon-clock c-current-datetime">
<span class="label">{{ currentDateTime }} UTC</span>
</div>
</template>
<script>
import moment from 'moment';
export default {
data() {
return {
currentDateTime: moment.utc().format('LTS')
}
},
mounted: function() {
setInterval(()=>{
this.currentDateTime = moment.utc().format('YYYY/MM/DD HH:mm:ss')
},100)
}
}
</script>

View File

@@ -123,12 +123,7 @@
.c-click-icon,
.c-button {
// Shrink buttons a bit when they appear in a frame
align-items: baseline;
font-size: 0.85em;
padding: 3px 5px;
&:before {
font-size: 0.8em;
}
font-size: 0.8em;
}
}
</style>

View File

@@ -61,8 +61,6 @@ export default {
if (this.composition) {
this.composition._destroy();
}
this.openmct.objectViews.off('clearData', this.clearData);
},
invokeEditModeHandler(editMode) {
this.currentView.onEditModeChange(editMode);
@@ -114,8 +112,6 @@ export default {
this.removeSelectable = openmct.selection.selectable(
this.$el, this.getSelectionContext(), true);
}
this.openmct.objectViews.on('clearData', this.clearData);
},
show(object, viewKey, immediatelySelect) {
if (this.unlisten) {
@@ -191,22 +187,6 @@ export default {
getComposableDomainObject(event) {
let serializedDomainObject = event.dataTransfer.getData('openmct/composable-domain-object');
return JSON.parse(serializedDomainObject);
},
clearData(domainObject) {
if (domainObject) {
let clearKeyString = this.openmct.objects.makeKeyString(domainObject.identifier),
currentObjectKeyString = this.openmct.objects.makeKeyString(this.currentObject.identifier);
if (clearKeyString === currentObjectKeyString) {
if (this.currentView.onClearData) {
this.currentView.onClearData();
}
}
} else {
if (this.currentView.onClearData) {
this.currentView.onClearData();
}
}
}
}
}

View File

@@ -25,6 +25,10 @@ import _ from 'lodash';
},
methods: {
updateSelection(selection) {
if (_.isEqual(this.selection, selection)) {
return;
}
this.selection = selection;
if (this.selectedViews) {
@@ -34,6 +38,10 @@ import _ from 'lodash';
this.$el.innerHTML = '';
}
if (selection.length > 1) {
return;
}
this.selectedViews = this.openmct.inspectorViews.get(selection);
this.selectedViews.forEach(selectedView => {
let viewContainer = document.createElement('div');

View File

@@ -2,14 +2,10 @@
<div class="l-shell" :class="{
'is-editing': isEditing
}">
<div class="l-shell__head" :class="{
'l-shell__head--expanded': headExpanded,
'l-shell__head--minify-indicators': !headExpanded
}">
<div class="l-shell__head">
<CreateButton class="l-shell__create-button"></CreateButton>
<indicators class="l-shell__head-section l-shell__indicators">
</indicators>
<notification-banner></notification-banner>
<indicators class="l-shell__head-section l-shell__indicators"></indicators>
<notification-banner></notification-banner> <!-- TODO: MAKE SURE THIS PLACEMENT WORKS PROPERLY -->
<div class="l-shell__head-section l-shell__controls">
<button class="c-icon-button c-icon-button--major icon-new-window" title="Open in a new browser tab"
@click="openInNewTab"
@@ -21,8 +17,8 @@
</button>
</div>
<app-logo></app-logo>
<button class="l-shell__head__collapse-button c-button"
@click="toggleShellHead"></button>
<!--button class="l-shell__head__collapse-button c-button"
@click="toggleShellHead"></button-->
</div>
<multipane class="l-shell__main"
type="horizontal">
@@ -66,6 +62,14 @@
flex-flow: column nowrap;
overflow: hidden;
/* &__status {
min-width: 95%;
margin-right: 1%;
background: $colorStatusBarBg;
color: $colorStatusBarFg;
padding: $interiorMarginSm;
}*/
&__pane-tree {
width: 40%;
@@ -159,7 +163,7 @@
}
&__head {
align-items: stretch;
align-items: center;
background: $colorHeadBg;
justify-content: space-between;
padding: $interiorMargin $interiorMargin + 2;
@@ -168,43 +172,19 @@
margin-left: $interiorMargin;
}
[class*='__head__collapse-button'] {
align-self: start;
$p: 6px;
padding-left: $p !important;
padding-right: $p !important;
&:before {
content: $glyph-icon-arrow-down;
font-size: 1.1em;
}
[class*='__collapse-button']:before {
content: $glyph-icon-arrow-down;
font-size: 1.1em;
}
&-section {
// Subdivides elements across the head
@include ellipsize();
border-right: 1px solid $colorInteriorBorder;
display: flex;
flex: 0 1 auto;
padding: 0 $interiorMargin;
padding-right: $interiorMargin;
}
&--expanded {
.c-indicator__label {
transition: none !important;
}
[class*='__head__collapse-button'] {
&:before {
transform: rotate(180deg);
}
}
}
}
&__controls {
$brdr: 1px solid $colorInteriorBorder;
border-right: $brdr;
border-left: $brdr;
align-items: start;
}
&__create-button,
@@ -215,14 +195,8 @@
&__create-button { margin-right: $interiorMarginLg; }
&__indicators {
//@include test();
flex: 1 1 auto;
flex-wrap: wrap;
[class*='indicator-clock'] { order: 90; }
.c-indicator .label {
font-size: 0.9em;
}
[class*='indicator-clock'] { order: 99; }
}
/******************************* MAIN AREA */
@@ -366,18 +340,11 @@
this.openmct.selection.on('change', this.toggleHasToolbar);
},
data: function () {
let storedHeadProps = window.localStorage.getItem('openmct-shell-head');
let headExpanded = true;
if (storedHeadProps) {
headExpanded = JSON.parse(storedHeadProps).expanded;
}
return {
fullScreen: false,
conductorComponent: undefined,
isEditing: false,
hasToolbar: false,
headExpanded
hasToolbar: false
}
},
computed: {
@@ -386,18 +353,6 @@
}
},
methods: {
toggleShellHead() {
this.headExpanded = !this.headExpanded;
window.localStorage.setItem(
'openmct-shell-head',
JSON.stringify(
{
expanded: this.headExpanded
}
)
);
},
fullScreenToggle() {
if (this.fullScreen) {
this.fullScreen = false;
@@ -420,6 +375,9 @@
}
this.hasToolbar = structure.length > 0;
},
toggleShellHead() {
return true;
}
}
}

View File

@@ -22,20 +22,70 @@
<style lang="scss">
@import "~styles/sass-base";
.c-indicator {
@include cControl();
@include cClickIconButtonLayout();
button { text-transform: uppercase; }
.l-indicators {
display: flex;
align-items: center;
}
background: none !important;
border-radius: $controlCr;
overflow: visible;
position: relative;
.c-indicator {
@include cClickIconButtonLayout();
&--clickable {
@include cClickIconButton();
@include hasMenu();
}
$bg: rgba(white, 0.2) !important;
$hbg: $colorStatusBarBg;
$hshdw: rgba(white, 0.4) 0 0 3px;
$br: $controlCr;
$hoverYOffset: -35px;
/*background: transparent !important;*/
border-radius: $br;
/*display: inline-block;*/
/*position: relative;*/
//padding: 1px $interiorMarginSm; // Use padding instead of margin to keep hover chatter to a minimum
text-transform: uppercase;
&:before {
/*display: inline-block;*/
}
&.no-minify {
// For items that cannot be minified
.label {
// Hover bubbles that appear when hovering on an Indicator
display: inline-block;
a,
button,
s-button,
.c-button {
// Make <a> in label look like buttons
transition: $transIn;
background: transparent;
border: 1px solid rgba($colorStatusBarFg, 0.5);
border-radius: $br;
box-sizing: border-box;
color: inherit;
font-size: inherit;
height: auto;
line-height: normal;
padding: 0 2px;
&:hover {
background: $bg;
color: #fff;
}
}
[class*='icon-'] {
// If any elements within label include the class 'icon-*' then deal with their :before's
&:before {
font-size: 0.8em;
margin-right: $interiorMarginSm;
}
}
}
&.no-collapse {
display: flex;
flex-flow: row nowrap;
align-items: center;
@@ -50,78 +100,24 @@
}
}
&:not(.no-minify) {
&:not(.no-collapse) {
&:before {
margin-right: 0 !important;
}
}
}
.c-indicator__label {
// Label element. Appears as a hover bubble element when Indicators are minified;
// Appears as an inline element when not.
display: inline-block;
transition:none;
white-space: nowrap;
a,
button,
s-button,
.c-button {
// Make <a> in label look like buttons
transition: $transIn;
background: transparent;
border: 1px solid rgba($colorIndicatorMenuFg, 0.5);
border-radius: $controlCr;
box-sizing: border-box;
color: inherit;
font-size: inherit;
height: auto;
line-height: normal;
padding: 0 2px;
&:hover {
background: rgba($colorIndicatorMenuFg, 0.1);
border-color: rgba($colorIndicatorMenuFg, 0.75);
color: $colorIndicatorMenuFgHov;
}
}
[class*='icon-'] {
// If any elements within label include the class 'icon-*' then deal with their :before's
&:before {
font-size: 0.8em;
margin-right: $interiorMarginSm;
}
}
}
.c-indicator__count {
display: none; // Only displays when Indicator is minified, see below
}
[class*='minify-indicators'] {
// All styles for minified Indicators should go in here
.c-indicator:not(.no-minify) {
@include hover() {
background: $colorIndicatorBgHov;
.c-indicator__label {
box-shadow: $colorIndicatorMenuBgShdw;
transform: scale(1.0);
transition: transform 100ms ease-out 100ms;
}
}
.c-indicator__label {
transition: transform 250ms ease-in 200ms;
background: $colorIndicatorMenuBg;
color: $colorIndicatorMenuFg;
border-radius: $controlCr;
.label {
transition: all 250ms ease-in 100ms;
background: $hbg;
border-radius: $br;
font-size: .6rem;
left: 0;
top: 130%;
padding: $interiorMargin $interiorMargin;
top: 140%;
opacity: 0;
padding: $interiorMarginSm $interiorMargin;
position: absolute;
transform-origin: 10px 0;
transform-origin: 10px 100%;
transform: scale(0.0);
overflow: visible;
white-space: nowrap;
z-index: 50;
&:before {
@@ -130,14 +126,13 @@
display: block;
position: absolute;
bottom: 100%;
@include triangle('up', $size: 4px, $ratio: 1, $color: $colorIndicatorMenuBg);
@include triangle('up', $size: 4px, $ratio: 1, $color: $hbg);
}
}
}
.c-indicator__count {
display: inline-block;
margin-left: $interiorMarginSm;
}
&.float-right {
float: right;
}
}
@@ -156,6 +151,12 @@
mounted() {
this.openmct.indicators.indicatorObjects.forEach((indicator) => {
// So that we can consistently position indicator elements,
// guarantee that they are wrapped in an element we control
// CH: fuck that...
// var wrapperNode = document.createElement('span');
// wrapperNode.className = 'u-contents';
// wrapperNode.appendChild(indicator.element);
this.$el.appendChild(indicator.element);
});
}

View File

@@ -57,19 +57,20 @@
.c-message-banner {
$closeBtnSize: 7px;
$m: 1px;
border-radius: $controlCr;
@include statusBannerColors($colorStatusDefault, $colorStatusFg);
cursor: pointer;
display: flex;
align-items: center;
left: 50%;
top: 50%;
max-width: 50%;
max-height: 25px;
padding: $interiorMarginSm $interiorMargin $interiorMarginSm $interiorMarginLg;
padding: $interiorMargin $interiorMargin $interiorMargin $interiorMarginLg;
position: absolute;
transform: translate(-50%, -50%);
transform: translateX(-50%);
bottom: $m;
z-index: 2;
> * + * {

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
/*global console */
define(['EventEmitter'], function (EventEmitter) {
define([], function () {
const DEFAULT_VIEW_PRIORITY = 100;
/**
@@ -31,12 +31,9 @@ define(['EventEmitter'], function (EventEmitter) {
* @memberof module:openmct
*/
function ViewRegistry() {
EventEmitter.apply(this);
this.providers = {};
}
ViewRegistry.prototype = Object.create(EventEmitter.prototype);
/**
* @private for platform-internal use

View File

@@ -24,7 +24,6 @@ const webpackConfig = {
output: {
filename: '[name].js',
library: '[name]',
libraryTarget: 'umd',
path: path.resolve(__dirname, 'dist')
},
resolve: {
@@ -36,7 +35,6 @@ const webpackConfig = {
"bourbon": "bourbon.scss",
"vue": path.join(__dirname, "node_modules/vue/dist/vue.js"),
"d3-scale": path.join(__dirname, "node_modules/d3-scale/build/d3-scale.min.js"),
"printj": path.join(__dirname, "node_modules/printj/dist/printj.min.js"),
"styles": path.join(__dirname, "src/styles-new")
}
},