Compare commits
91 Commits
alpha-enum
...
maelstrom2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25ec6b6943 | ||
|
|
b628814f78 | ||
|
|
a15ad6fc4c | ||
|
|
767aa78b06 | ||
|
|
43b7efa775 | ||
|
|
ac18548b42 | ||
|
|
ed3c226909 | ||
|
|
aafe524454 | ||
|
|
e84ade1752 | ||
|
|
3b094e43e3 | ||
|
|
e6a7b4ed6c | ||
|
|
97230bb21f | ||
|
|
768d99d928 | ||
|
|
c760190a29 | ||
|
|
7fe4a77c43 | ||
|
|
8578d78c51 | ||
|
|
362e565a09 | ||
|
|
9517c1f2cd | ||
|
|
262d35804d | ||
|
|
e0587bf0e7 | ||
|
|
f1494fd285 | ||
|
|
884aec8ea0 | ||
|
|
216f447578 | ||
|
|
261e8e8759 | ||
|
|
cb6a8629d3 | ||
|
|
9eead672d8 | ||
|
|
5da6b2c969 | ||
|
|
4780cde3b5 | ||
|
|
1960215fc1 | ||
|
|
d06e3e12fc | ||
|
|
365998ad4f | ||
|
|
15cfa79106 | ||
|
|
6857e15a83 | ||
|
|
f1294f3e73 | ||
|
|
d4a1f6eb35 | ||
|
|
4c7fb0d3eb | ||
|
|
b9017329cd | ||
|
|
b08834a53b | ||
|
|
eb7330522e | ||
|
|
0c1cdf1d8e | ||
|
|
8dedf52910 | ||
|
|
0420eac159 | ||
|
|
715e3419a0 | ||
|
|
e6ab3ccf85 | ||
|
|
edf748d4a1 | ||
|
|
84ba444eb5 | ||
|
|
6d9f3f1e3e | ||
|
|
ae32b902a7 | ||
|
|
660bf805d0 | ||
|
|
2f58ea9c1f | ||
|
|
ba09a17b29 | ||
|
|
5063fa1fb1 | ||
|
|
543b4dab4c | ||
|
|
ef310a8777 | ||
|
|
7d07a9e21f | ||
|
|
ada18faa98 | ||
|
|
95d40aaeed | ||
|
|
b59f5c70dc | ||
|
|
94e7351e22 | ||
|
|
50ee7353b1 | ||
|
|
df524c4f48 | ||
|
|
aa59692585 | ||
|
|
0bf82956ab | ||
|
|
f102158ba0 | ||
|
|
9a51bb71b9 | ||
|
|
12b9aa75a3 | ||
|
|
5bedfc2efd | ||
|
|
212d7c3eae | ||
|
|
d7a3510f34 | ||
|
|
9cc44dcc4e | ||
|
|
f42a5e19f0 | ||
|
|
102cfc33c4 | ||
|
|
957c7102fe | ||
|
|
0519824109 | ||
|
|
4380f88a08 | ||
|
|
20d5db6e44 | ||
|
|
5978b8e19d | ||
|
|
a0b71f92b8 | ||
|
|
7c3f7ff384 | ||
|
|
6f2a567299 | ||
|
|
746badd065 | ||
|
|
7d99877eb9 | ||
|
|
3eac91a6d9 | ||
|
|
4d426580ae | ||
|
|
9270f02ca4 | ||
|
|
815b1449f4 | ||
|
|
0874ada4d2 | ||
|
|
03812437d3 | ||
|
|
2b8272cf05 | ||
|
|
71a2f27e0c | ||
|
|
5460ca2009 |
487
configuration_json/MaelstromDictionary.js
Normal file
487
configuration_json/MaelstromDictionary.js
Normal file
@@ -0,0 +1,487 @@
|
||||
export default {
|
||||
'telemetry': {
|
||||
type: 'folder',
|
||||
name: 'Maelstrom Telemetry',
|
||||
type: 'folder',
|
||||
location: 'ROOT',
|
||||
composition: [
|
||||
{
|
||||
namespace: 'maelstrom',
|
||||
key: 'velocity'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'acceleration-ms-2'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'acceleration-g'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'distance'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'distance-m'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'roll'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'pitch'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'yaw'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'event-index'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'event-time-str'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'ring'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'next-los'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'evr-1'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'evr-2'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'evr-3'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'evr-4'
|
||||
},{
|
||||
namespace: 'maelstrom',
|
||||
key: 'evr-5'
|
||||
}
|
||||
]
|
||||
},
|
||||
'velocity': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Velocity',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Velocity",
|
||||
"units": "ms",
|
||||
"format": "float",
|
||||
"source": "velocity",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'acceleration-ms-2': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Acceleration (ms^-2)',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Acceleration",
|
||||
"units": "ms^-2",
|
||||
"format": "float",
|
||||
"source": "acceleration-ms-2",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'acceleration-g': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Acceleration (G)',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Acceleration",
|
||||
"units": "ms^-2",
|
||||
"format": "float",
|
||||
"source": "acceleration-g",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'distance': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Distance (km)',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Distance",
|
||||
"units": "km",
|
||||
"format": "float",
|
||||
"source": "distance-km",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'distance-m': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Distance (m)',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Distance Meters",
|
||||
"units": "m",
|
||||
"format": "float",
|
||||
"source": "distance-m",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'roll': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Roll',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Roll",
|
||||
"units": "degrees",
|
||||
"format": "float",
|
||||
"source": "roll",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'pitch': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Pitch',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Pitch",
|
||||
"units": "degrees",
|
||||
"format": "float",
|
||||
"source": "pitch",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'yaw': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Yaw',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Yaw",
|
||||
"units": "degrees",
|
||||
"format": "float",
|
||||
"source": "yaw",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'event-index': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Event Index',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Event Index",
|
||||
"units": "i",
|
||||
"format": "float",
|
||||
"source": "event-index",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'event-time-str': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Event Time Str',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Event Time Str",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "event-time-str",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'ring': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Ring',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Ring",
|
||||
"units": "",
|
||||
"format": "int",
|
||||
"source": "ring",
|
||||
"hints": {
|
||||
"range": 24
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'next-los': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'Next LOS',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "Next LOS",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "next-los",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'evr-1': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'EVR 1',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "EVR-1",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "evr-1",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'evr-2': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'EVR 2',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "EVR-2",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "evr-2",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'evr-3': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'EVR 3',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "EVR-3",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "evr-3",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'evr-4': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'EVR 4',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "EVR-4",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "evr-4",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
},
|
||||
'evr-5': {
|
||||
type: 'maelstrom-telemetry',
|
||||
location: 'maelstrom:telemetry',
|
||||
name: 'EVR 5',
|
||||
telemetry: {
|
||||
values: [{
|
||||
"key": "value",
|
||||
"name": "EVR-5",
|
||||
"units": "",
|
||||
"format": "string",
|
||||
"source": "evr-5",
|
||||
"hints": {
|
||||
"range": 1
|
||||
}
|
||||
}, {
|
||||
"key": "utc",
|
||||
"source": "event_time",
|
||||
"name": "Time",
|
||||
"format": "utc-diy",
|
||||
"hints": {
|
||||
"domain": 1
|
||||
}
|
||||
}
|
||||
]}
|
||||
}
|
||||
}
|
||||
1
configuration_json/maelstrom2-final-v1-my-items.json
Normal file
1
configuration_json/maelstrom2-final-v1-my-items.json
Normal file
File diff suppressed because one or more lines are too long
@@ -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;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<span class="h-indicator" ng-controller="DialogLaunchController">
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div class="ls-indicator 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>
|
||||
<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>
|
||||
</span></div>
|
||||
</span>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<span class="h-indicator" ng-controller="NotificationLaunchController">
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div class="ls-indicator 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>
|
||||
<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>
|
||||
</span></div>
|
||||
</span>
|
||||
|
||||
@@ -45,12 +45,13 @@
|
||||
].forEach(
|
||||
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
|
||||
);
|
||||
openmct.install(openmct.plugins.Bignumbers());
|
||||
openmct.install(openmct.plugins.Gauge());
|
||||
openmct.install(openmct.plugins.MyItems());
|
||||
openmct.install(openmct.plugins.LocalStorage());
|
||||
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"
|
||||
}));
|
||||
@@ -80,13 +81,9 @@
|
||||
}));
|
||||
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.GoToOriginalAction());
|
||||
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
|
||||
openmct.start();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
{
|
||||
"name": "openmct",
|
||||
"version": "0.14.0-SNAPSHOT",
|
||||
"version": "1.0.0-beta",
|
||||
"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",
|
||||
@@ -55,7 +56,7 @@
|
||||
"node-bourbon": "^4.2.3",
|
||||
"node-sass": "^4.9.2",
|
||||
"painterro": "^0.2.65",
|
||||
"printj": "^1.1.0",
|
||||
"printj": "^1.2.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"request": "^2.69.0",
|
||||
"split": "^1.0.0",
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div class="ls-indicator {{ngModel.getCssClass()}}"
|
||||
<div class="c-indicator {{ngModel.getCssClass()}}"
|
||||
title="{{ngModel.getDescription()}}"
|
||||
ng-show="ngModel.getText().length > 0">
|
||||
<span class="label">{{ngModel.getText()}}</span>
|
||||
<span class="label c-indicator__label">{{ngModel.getText()}}</span>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
|
||||
<div ng-show="notifications.length > 0" class="ls-indicator s-status-{{highest.severity}} icon-bell"
|
||||
<div ng-show="notifications.length > 0" class="c-indicator c-indicator--clickable s-status-{{highest.severity}} icon-bell"
|
||||
ng-controller="NotificationIndicatorController">
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
|
||||
@@ -49,7 +49,7 @@ define(
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getCssClass = function () {
|
||||
return "t-indicator-clock icon-clock no-collapse float-right";
|
||||
return "t-indicator-clock icon-clock no-minify c-indicator--not-clickable";
|
||||
};
|
||||
|
||||
ClockIndicator.prototype.getText = function () {
|
||||
|
||||
@@ -64,12 +64,30 @@ 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');
|
||||
|
||||
// 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);
|
||||
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();
|
||||
}
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ImportAsJSONAction.prototype.deepInstantiate = function (parent, tree, seen) {
|
||||
|
||||
@@ -100,7 +100,7 @@ define(
|
||||
}
|
||||
|
||||
CouchIndicator.prototype.getCssClass = function () {
|
||||
return "icon-database " + this.state.statusClass;
|
||||
return "c-indicator--clickable icon-database " + this.state.statusClass;
|
||||
};
|
||||
|
||||
CouchIndicator.prototype.getGlyphClass = function () {
|
||||
|
||||
@@ -84,7 +84,7 @@ define(
|
||||
}
|
||||
|
||||
ElasticIndicator.prototype.getCssClass = function () {
|
||||
return "icon-database";
|
||||
return "c-indicator--clickable icon-database";
|
||||
};
|
||||
ElasticIndicator.prototype.getGlyphClass = function () {
|
||||
return this.state.glyphClass;
|
||||
|
||||
@@ -41,7 +41,7 @@ define(
|
||||
}
|
||||
|
||||
LocalStorageIndicator.prototype.getCssClass = function () {
|
||||
return "icon-database s-status-caution";
|
||||
return "c-indicator--clickable icon-database s-status-caution";
|
||||
};
|
||||
LocalStorageIndicator.prototype.getGlyphClass = function () {
|
||||
return 'caution';
|
||||
|
||||
@@ -246,12 +246,21 @@ 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));
|
||||
|
||||
@@ -26,6 +26,7 @@ const OUTSIDE_EDIT_PATH_BLACKLIST = ["copy", "follow", "properties", "move", "li
|
||||
export default class LegacyContextMenuAction {
|
||||
constructor(openmct, LegacyAction) {
|
||||
this.openmct = openmct;
|
||||
this.key = LegacyAction.definition.key;
|
||||
this.name = LegacyAction.definition.name;
|
||||
this.description = LegacyAction.definition.description;
|
||||
this.cssClass = LegacyAction.definition.cssClass;
|
||||
|
||||
@@ -108,6 +108,9 @@ define([
|
||||
link();
|
||||
}
|
||||
},
|
||||
onClearData() {
|
||||
scope.$broadcast('clearData');
|
||||
},
|
||||
destroy: function () {
|
||||
element.off();
|
||||
element.remove();
|
||||
|
||||
@@ -25,7 +25,7 @@ define([
|
||||
cssClass: representation.cssClass,
|
||||
description: representation.description,
|
||||
canView: function (selection) {
|
||||
if (selection.length === 0 || selection[0].length === 0) {
|
||||
if (selection.length !== 1 || selection[0].length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,9 @@ class ContextMenuAPI {
|
||||
* a single sentence or short paragraph) of this kind of view
|
||||
* @property {string} cssClass the CSS class to apply to labels for this
|
||||
* view (to add icons, for instance)
|
||||
* @property {string} key unique key to identify the context menu action
|
||||
* (used in custom context menu eg table rows, to identify which actions to include)
|
||||
* @property {boolean} hideInDefaultMenu optional flag to hide action from showing in the default context menu (tree item)
|
||||
*/
|
||||
/**
|
||||
* @method appliesTo
|
||||
@@ -72,12 +75,21 @@ class ContextMenuAPI {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_showContextMenuForObjectPath(objectPath, x, y) {
|
||||
_showContextMenuForObjectPath(objectPath, x, y, actionsToBeIncluded) {
|
||||
|
||||
let applicableActions = this._allActions.filter((action) => {
|
||||
if (action.appliesTo === undefined) {
|
||||
return true;
|
||||
|
||||
if (actionsToBeIncluded) {
|
||||
if (action.appliesTo === undefined && actionsToBeIncluded.includes(action.key)) {
|
||||
return true;
|
||||
}
|
||||
return action.appliesTo(objectPath, actionsToBeIncluded) && actionsToBeIncluded.includes(action.key);
|
||||
} else {
|
||||
if (action.appliesTo === undefined) {
|
||||
return true;
|
||||
}
|
||||
return action.appliesTo(objectPath) && !action.hideInDefaultMenu;
|
||||
}
|
||||
return action.appliesTo(objectPath);
|
||||
});
|
||||
|
||||
if (this._activeContextMenu) {
|
||||
|
||||
@@ -28,7 +28,7 @@ define(['zepto', './res/indicator-template.html'],
|
||||
this.openmct = openmct;
|
||||
this.element = $(indicatorTemplate)[0];
|
||||
|
||||
this.textElement = this.element.querySelector('.indicator-text');
|
||||
this.textElement = this.element.querySelector('.js-indicator-text');
|
||||
|
||||
//Set defaults
|
||||
this.text('New Indicator');
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<div class="ls-indicator" title="">
|
||||
<span class="label indicator-text"></span>
|
||||
<div class="c-indicator c-indicator--clickable c-indicator--simple" title="">
|
||||
<span class="label js-indicator-text c-indicator__label"></span>
|
||||
</div>
|
||||
|
||||
@@ -93,7 +93,7 @@
|
||||
&.message-severity-error:before {
|
||||
@include legacyMessage();
|
||||
content: $glyph-icon-alert-triangle;
|
||||
color: $colorWarningLo;
|
||||
color: $colorWarningHi;
|
||||
}
|
||||
|
||||
// Messages in a list
|
||||
|
||||
@@ -69,6 +69,7 @@
|
||||
flex: 1 1 auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__top-bar {
|
||||
|
||||
@@ -38,7 +38,7 @@ define([
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'LadTableSet';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
view: function (domainObject, isEditing, objectPath) {
|
||||
let component;
|
||||
|
||||
return {
|
||||
@@ -49,7 +49,8 @@ define([
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject
|
||||
domainObject,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-set></lad-table-set>'
|
||||
|
||||
@@ -38,7 +38,7 @@ define([
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'LadTable';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
view: function (domainObject, isEditing, objectPath) {
|
||||
let component;
|
||||
|
||||
return {
|
||||
@@ -49,7 +49,8 @@ define([
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject
|
||||
domainObject,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<lad-table-component></lad-table-component>'
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
@@ -21,7 +22,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<tr>
|
||||
<tr @contextmenu.prevent="showContextMenu">
|
||||
<td>{{name}}</td>
|
||||
<td>{{timestamp}}</td>
|
||||
<td :class="valueClass">
|
||||
@@ -35,15 +36,25 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
const CONTEXT_MENU_ACTIONS = [
|
||||
'viewHistoricalData',
|
||||
'remove'
|
||||
];
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: ['domainObject'],
|
||||
data() {
|
||||
let currentObjectPath = this.objectPath.slice();
|
||||
currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
return {
|
||||
name: this.domainObject.name,
|
||||
timestamp: '---',
|
||||
value: '---',
|
||||
valueClass: ''
|
||||
valueClass: '',
|
||||
currentObjectPath
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -73,11 +84,15 @@ export default {
|
||||
.request(this.domainObject, {strategy: 'latest'})
|
||||
.then((array) => this.updateValues(array[array.length - 1]));
|
||||
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.keyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
|
||||
|
||||
this.limitEvaluator = openmct
|
||||
.telemetry
|
||||
|
||||
@@ -44,7 +44,7 @@ import lodash from 'lodash';
|
||||
import LadRow from './LADRow.vue';
|
||||
|
||||
export default {
|
||||
inject: ['openmct', 'domainObject'],
|
||||
inject: ['openmct', 'domainObject', 'objectPath'],
|
||||
components: {
|
||||
LadRow
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* 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
|
||||
* You may obtain a copy of the License atw
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
|
||||
71
src/plugins/bignumbers/bignumbers.js
Normal file
71
src/plugins/bignumbers/bignumbers.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* 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/bignumbers.vue',
|
||||
'vue'
|
||||
], function (
|
||||
BignumbersComponent,
|
||||
Vue
|
||||
) {
|
||||
function Bignumbers(openmct) {
|
||||
return {
|
||||
key: 'bignumbers',
|
||||
name: 'Bignumbers',
|
||||
cssClass: 'icon-telemetry',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'bignumbers';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'bignumbers';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
components: {
|
||||
BignumbersComponent: BignumbersComponent.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
composition: openmct.composition.get(domainObject)
|
||||
},
|
||||
el: element,
|
||||
template: '<bignumbers-component></bignumbers-component>'
|
||||
});
|
||||
},
|
||||
destroy: function (element) {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
priority: function () {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
return Bignumbers;
|
||||
});
|
||||
131
src/plugins/bignumbers/components/bignumbers.vue
Normal file
131
src/plugins/bignumbers/components/bignumbers.vue
Normal file
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div class="c-bignumbers">
|
||||
<svg class="c-bignumbers__int" viewBox="0 0 52 32">
|
||||
<text textLength=100% lengthAdjust=spacingAndGlyphs x="0" y="32">{{ this.curValInt }}</text>
|
||||
</svg>
|
||||
<svg class="c-bignumbers__dec" viewBox="0 0 40 20">
|
||||
<text textLength=100% lengthAdjust=spacing x="0" y="20">.{{ this.curValDec }}</text>
|
||||
</svg>
|
||||
<svg class="c-bignumbers__units" viewBox="0 0 45 11">
|
||||
<text textLength=100% lengthAdjust=spacingAndGlyphs x="0" y="11">{{ this.units }}</text>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-bignumbers {
|
||||
$w1: 53%;
|
||||
|
||||
@include abs();
|
||||
bottom: auto;
|
||||
padding-bottom: 33%;
|
||||
|
||||
&__int,
|
||||
&__dec,
|
||||
&__units {
|
||||
position: absolute;
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
&__int,
|
||||
&__dec {
|
||||
font-family: $heroFont;
|
||||
}
|
||||
|
||||
&__int {
|
||||
font-size: 51px;
|
||||
opacity: 0.8;
|
||||
width: $w1;
|
||||
}
|
||||
|
||||
&__dec {
|
||||
left: $w1;
|
||||
font-size: 32px;
|
||||
opacity: 0.4;
|
||||
width: 100% - $w1;
|
||||
}
|
||||
|
||||
&__units {
|
||||
font-size: 9px;
|
||||
font-family: $headerFont;
|
||||
left: $w1;
|
||||
bottom: 0;
|
||||
opacity: 0.2;
|
||||
width: 99% - $w1; // Font has different char spacing, so use reduced width
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "bignumbers",
|
||||
inject: ['openmct', 'domainObject', 'composition'],
|
||||
data: function () {
|
||||
let config = this.domainObject.configuration,
|
||||
units = config.units;
|
||||
console.log(config);
|
||||
return {
|
||||
curValInt: 0,
|
||||
curValDec: 0,
|
||||
units: units
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getInt: function(val, digits) {
|
||||
// Extract integer portion of val and zero-pad it if its length < digits
|
||||
return this.zeroPad(Math.floor(val), digits);
|
||||
},
|
||||
getDec: function(val, digits) {
|
||||
// Extract decimal portion of val to the specified number of digits
|
||||
return Number.parseFloat(val).toFixed(digits).split('.')[1];
|
||||
},
|
||||
zeroPad: function(val, length) {
|
||||
// Zero pads an integer and returns it as a string
|
||||
let s = Math.abs(val).toString();
|
||||
if (s.length < length) {
|
||||
for (let i = 0; i <= (length - s.length); i++) {
|
||||
s = '0' + s;
|
||||
}
|
||||
}
|
||||
if (val < 0) {
|
||||
s = '-' + s;
|
||||
}
|
||||
return s;
|
||||
},
|
||||
updateValue(datum) {
|
||||
let cv = this.formats[this.valueKey].format(datum);
|
||||
this.curValInt = this.getInt(cv, 3);
|
||||
this.curValDec = this.getDec(cv, 3);
|
||||
},
|
||||
subscribe(domainObject) {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
|
||||
this.valueKey = this
|
||||
.metadata
|
||||
.valuesForHints(['range'])[0].key;
|
||||
this.unsubscribe = this.openmct
|
||||
.telemetry
|
||||
.subscribe(domainObject, this.updateValue.bind(this), {});
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(domainObject, {strategy: 'latest'})
|
||||
.then((values) => values.forEach(this.updateValue));
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
mounted() {
|
||||
this.composition.on('add', this.subscribe);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.subscribe);
|
||||
this.unsubscribe();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
58
src/plugins/bignumbers/plugin.js
Normal file
58
src/plugins/bignumbers/plugin.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/*****************************************************************************
|
||||
* 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([
|
||||
'./bignumbers'
|
||||
], function (
|
||||
Bignumbers
|
||||
) {
|
||||
return function plugin() {
|
||||
return function install(openmct) {
|
||||
openmct.objectViews.addProvider(new Bignumbers(openmct));
|
||||
|
||||
openmct.types.addType('bignumbers', {
|
||||
name: "Big Numbers",
|
||||
creatable: true,
|
||||
description: "Display the value of a telemetry element with units in a stylized numeric view.",
|
||||
cssClass: 'icon-telemetry',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
domainObject.configuration = {
|
||||
units: ''
|
||||
};
|
||||
},
|
||||
form: [
|
||||
{
|
||||
name: "Units",
|
||||
control: "textfield",
|
||||
cssClass: "",
|
||||
key: "units",
|
||||
property: [
|
||||
"configuration",
|
||||
"units"
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
||||
39
src/plugins/clearData/clearDataAction.js
Normal file
39
src/plugins/clearData/clearDataAction.js
Normal file
@@ -0,0 +1,39 @@
|
||||
/*****************************************************************************
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
18
src/plugins/clearData/components/globalClearIndicator.vue
Normal file
18
src/plugins/clearData/components/globalClearIndicator.vue
Normal file
@@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<div class="c-indicator c-indicator--clickable icon-session">
|
||||
<span class="label c-indicator__label">
|
||||
<button @click="globalClearEmit">Clear All Data</button>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
methods: {
|
||||
globalClearEmit() {
|
||||
this.openmct.objectViews.emit('clearData');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
54
src/plugins/clearData/plugin.js
Normal file
54
src/plugins/clearData/plugin.js
Normal file
@@ -0,0 +1,54 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2019, 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/globalClearIndicator.vue',
|
||||
'./clearDataAction',
|
||||
'vue'
|
||||
], function (
|
||||
GlobaClearIndicator,
|
||||
ClearDataAction,
|
||||
Vue
|
||||
) {
|
||||
return function plugin(appliesToObjects) {
|
||||
appliesToObjects = appliesToObjects || [];
|
||||
|
||||
return function install(openmct) {
|
||||
let component = new Vue ({
|
||||
provide: {
|
||||
openmct
|
||||
},
|
||||
components: {
|
||||
GlobalClearIndicator: GlobaClearIndicator.default
|
||||
},
|
||||
template: '<GlobalClearIndicator></GlobalClearIndicator>'
|
||||
}),
|
||||
indicator = {
|
||||
element: component.$mount().$el
|
||||
};
|
||||
|
||||
openmct.indicators.add(indicator);
|
||||
|
||||
openmct.contextMenu.registerAction(new ClearDataAction.default(openmct, appliesToObjects));
|
||||
};
|
||||
};
|
||||
});
|
||||
62
src/plugins/clearData/test/clearDataActionSpec.js
Normal file
62
src/plugins/clearData/test/clearDataActionSpec.js
Normal file
@@ -0,0 +1,62 @@
|
||||
/*****************************************************************************
|
||||
* 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]);
|
||||
});
|
||||
});
|
||||
78
src/plugins/displayLayout/AlphanumericFormatViewProvider.js
Normal file
78
src/plugins/displayLayout/AlphanumericFormatViewProvider.js
Normal file
@@ -0,0 +1,78 @@
|
||||
/*****************************************************************************
|
||||
* 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 (domainObject, isEditing, objectPath) {
|
||||
let component;
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
provide: {
|
||||
openmct,
|
||||
objectPath
|
||||
},
|
||||
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;
|
||||
});
|
||||
@@ -0,0 +1,90 @@
|
||||
/*****************************************************************************
|
||||
* 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>
|
||||
@@ -48,7 +48,8 @@
|
||||
:multiSelect="selectedLayoutItems.length > 1"
|
||||
@move="move"
|
||||
@endMove="endMove"
|
||||
@endLineResize='endLineResize'>
|
||||
@endLineResize='endLineResize'
|
||||
@formatChanged='updateTelemetryFormat'>
|
||||
</component>
|
||||
<edit-marquee v-if='showMarquee'
|
||||
:gridSize="gridSize"
|
||||
@@ -201,7 +202,7 @@
|
||||
return selectionPath && selectionPath.length > 1 && !singleSelectedLine;
|
||||
}
|
||||
},
|
||||
inject: ['openmct', 'options'],
|
||||
inject: ['openmct', 'options', 'objectPath'],
|
||||
props: ['domainObject'],
|
||||
components: components,
|
||||
methods: {
|
||||
@@ -557,6 +558,11 @@
|
||||
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() {
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
@endMove="() => $emit('endMove')">
|
||||
<object-frame v-if="domainObject"
|
||||
:domain-object="domainObject"
|
||||
:object-path="objectPath"
|
||||
:object-path="currentObjectPath"
|
||||
:has-frame="item.hasFrame"
|
||||
:show-edit-view="false"
|
||||
ref="objectFrame">
|
||||
@@ -71,7 +71,7 @@
|
||||
hasFrame: hasFrameByDefault(domainObject.type)
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
@@ -81,7 +81,7 @@
|
||||
data() {
|
||||
return {
|
||||
domainObject: undefined,
|
||||
objectPath: []
|
||||
currentObjectPath: []
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@@ -100,7 +100,7 @@
|
||||
methods: {
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.objectPath = [this.domainObject].concat(this.openmct.router.path);
|
||||
this.currentObjectPath = [this.domainObject].concat(this.objectPath.slice());
|
||||
this.$nextTick(function () {
|
||||
let childContext = this.$refs.objectFrame.getSelectionContext();
|
||||
childContext.item = domainObject;
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
@endMove="() => $emit('endMove')">
|
||||
<div class="c-telemetry-view"
|
||||
:style="styleObject"
|
||||
v-if="domainObject">
|
||||
v-if="domainObject"
|
||||
@contextmenu.prevent="showContextMenu">
|
||||
<div v-if="showLabel"
|
||||
class="c-telemetry-view__label">
|
||||
<div class="c-telemetry-view__label-text">{{ domainObject.name }}</div>
|
||||
@@ -79,9 +80,11 @@
|
||||
|
||||
<script>
|
||||
import LayoutFrame from './LayoutFrame.vue'
|
||||
import printj from 'printj'
|
||||
|
||||
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5],
|
||||
DEFAULT_POSITION = [1, 1];
|
||||
DEFAULT_POSITION = [1, 1],
|
||||
CONTEXT_MENU_ACTIONS = ['viewHistoricalData'];
|
||||
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, domainObject, position) {
|
||||
@@ -102,7 +105,7 @@
|
||||
size: "13px"
|
||||
};
|
||||
},
|
||||
inject: ['openmct'],
|
||||
inject: ['openmct', 'objectPath'],
|
||||
props: {
|
||||
item: Object,
|
||||
gridSize: Array,
|
||||
@@ -143,6 +146,10 @@
|
||||
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() {
|
||||
@@ -158,7 +165,8 @@
|
||||
return {
|
||||
datum: undefined,
|
||||
formats: undefined,
|
||||
domainObject: undefined
|
||||
domainObject: undefined,
|
||||
currentObjectPath: undefined
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@@ -168,6 +176,9 @@
|
||||
}
|
||||
|
||||
this.context.index = newIndex;
|
||||
},
|
||||
item(newItem) {
|
||||
this.context.layoutItem = newItem;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -210,19 +221,30 @@
|
||||
},
|
||||
setObject(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.keyString = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
|
||||
this.limitEvaluator = this.openmct.telemetry.limitEvaluator(this.domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
this.requestHistoricalData();
|
||||
this.subscribeToObject();
|
||||
|
||||
this.currentObjectPath = this.objectPath.slice();
|
||||
this.currentObjectPath.unshift(this.domainObject);
|
||||
|
||||
this.context = {
|
||||
item: domainObject,
|
||||
layoutItem: this.item,
|
||||
index: this.index
|
||||
index: this.index,
|
||||
updateTelemetryFormat: this.updateTelemetryFormat
|
||||
};
|
||||
this.removeSelectable = this.openmct.selection.selectable(
|
||||
this.$el, this.context, this.initSelect);
|
||||
},
|
||||
updateTelemetryFormat(format) {
|
||||
this.$emit('formatChanged', this.item, format);
|
||||
},
|
||||
showContextMenu(event) {
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(this.currentObjectPath, event.x, event.y, CONTEXT_MENU_ACTIONS);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
||||
@@ -25,6 +25,8 @@ 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({
|
||||
@@ -35,7 +37,7 @@ export default function DisplayLayoutPlugin(options) {
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'layout';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
view: function (domainObject, isEditing, objectPath) {
|
||||
let component;
|
||||
return {
|
||||
show(container) {
|
||||
@@ -47,13 +49,14 @@ export default function DisplayLayoutPlugin(options) {
|
||||
provide: {
|
||||
openmct,
|
||||
objectUtils,
|
||||
options
|
||||
options,
|
||||
objectPath
|
||||
},
|
||||
el: container,
|
||||
data () {
|
||||
return {
|
||||
domainObject: domainObject
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -76,7 +79,8 @@ export default function DisplayLayoutPlugin(options) {
|
||||
}
|
||||
});
|
||||
openmct.types.addType('layout', DisplayLayoutType());
|
||||
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct));
|
||||
openmct.toolbars.addProvider(new DisplayLayoutToolbar(openmct, options));
|
||||
openmct.inspectorViews.addProvider(new AlphaNumericFormatViewProvider(openmct, options));
|
||||
openmct.composition.addPolicy((parent, child) => {
|
||||
if (parent.type === 'layout' && child.type === 'folder') {
|
||||
return false;
|
||||
|
||||
@@ -63,7 +63,13 @@ export default {
|
||||
|
||||
if (filterValue && filterValue[comparator]) {
|
||||
if (value === false) {
|
||||
filterValue[comparator] = filterValue[comparator].filter(v => v !== valueName);
|
||||
let filteredValueName = filterValue[comparator].filter(v => v !== valueName);
|
||||
|
||||
if (filteredValueName.length === 0) {
|
||||
delete this.updatedFilters[key];
|
||||
} else {
|
||||
filterValue[comparator] = filteredValueName;
|
||||
}
|
||||
} else {
|
||||
filterValue[comparator].push(valueName);
|
||||
}
|
||||
@@ -77,6 +83,14 @@ 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, '');
|
||||
|
||||
@@ -59,14 +59,18 @@ export default {
|
||||
removeChildren(identifier) {
|
||||
let keyString = this.openmct.objects.makeKeyString(identifier);
|
||||
this.$delete(this.children, keyString);
|
||||
this.persistFilters(keyString);
|
||||
delete this.persistedFilters[keyString];
|
||||
this.mutateConfigurationFilters();
|
||||
},
|
||||
persistFilters(keyString, userSelects) {
|
||||
this.persistedFilters[keyString] = userSelects;
|
||||
this.openmct.objects.mutate(this.providedObject, 'configuration.filters', this.persistedFilters);
|
||||
this.mutateConfigurationFilters();
|
||||
},
|
||||
updatePersistedFilters(filters) {
|
||||
this.persistedFilters = filters;
|
||||
},
|
||||
mutateConfigurationFilters() {
|
||||
this.openmct.objects.mutate(this.providedObject, 'configuration.filters', this.persistedFilters);
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
|
||||
202
src/plugins/gauge/components/gaugeRadial.vue
Normal file
202
src/plugins/gauge/components/gaugeRadial.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="c-gauge">
|
||||
<div class="c-gauge__wrapper">
|
||||
<svg class="c-gauge__range" viewBox="0 0 512 512">
|
||||
<text class="c-gauge__curval" transform="translate(256 310)" text-anchor="middle">{{ this.curVal }}</text>
|
||||
<text font-size="35" transform="translate(105 455) rotate(-45)"
|
||||
v-if="displayMinMax">{{ this.rangeLow }}</text>
|
||||
<text font-size="35" transform="translate(407 455) rotate(45)" text-anchor="end"
|
||||
v-if="displayMinMax">{{ this.rangeHigh }}</text>
|
||||
</svg>
|
||||
|
||||
<div class="c-dial">
|
||||
<svg class="c-dial__bg" viewBox="0 0 512 512">
|
||||
<g>
|
||||
<path d="M256,0C114.6,0,0,114.6,0,256S114.6,512,256,512,512,397.4,512,256,397.4,0,256,0Zm0,412A156,156,0,1,1,412,256,155.9,155.9,0,0,1,256,412Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<svg class="c-dial__limit" viewBox="0 0 512 512"
|
||||
v-if="degLimit < 270"
|
||||
:class="{
|
||||
'c-limit-clip--90': this.degLimit > 90,
|
||||
'c-limit-clip--180': this.degLimit >= 180
|
||||
}">
|
||||
<path d="M100,256A156,156,0,1,1,366.3,366.3L437,437a255.2,255.2,0,0,0,75-181C512,114.6,397.4,0,256,0S0,114.6,0,256A255.2,255.2,0,0,0,75,437l70.7-70.7A155.5,155.5,0,0,1,100,256Z"
|
||||
:style="`transform: rotate(${this.degLimit}deg)`"/>
|
||||
</svg>
|
||||
|
||||
<svg class="c-dial__value" viewBox="0 0 512 512"
|
||||
v-if="this.degValue > 0"
|
||||
:class="{
|
||||
'c-dial-clip--90': this.degValue < 90,
|
||||
'c-dial-clip--180': this.degValue >= 90 && this.degValue < 180
|
||||
}">
|
||||
<path d="M256,31A224.3,224.3,0,0,0,98.3,95.5l48.4,49.2a156,156,0,1,1-1,221.6L96.9,415.1A224.4,224.4,0,0,0,256,481c124.3,0,225-100.7,225-225S380.3,31,256,31Z"
|
||||
:style="`transform: rotate(${this.degValue}deg)`"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-gauge {
|
||||
@include abs();
|
||||
overflow: hidden;
|
||||
|
||||
&__wrapper {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
padding-bottom: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&__value {
|
||||
position: absolute;
|
||||
top: 50%; left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
font-size: 3vw;
|
||||
}
|
||||
|
||||
&__range {
|
||||
$o: 21%;
|
||||
position: absolute;
|
||||
fill: rgba(#fff, 0.8);
|
||||
}
|
||||
|
||||
&__curval {
|
||||
font-family: $heroFont;
|
||||
font-size: 170px;
|
||||
}
|
||||
}
|
||||
|
||||
.c-dial {
|
||||
// Dial elements
|
||||
@include abs();
|
||||
clip-path: polygon(0 0, 100% 0, 100% 100%, 50% 50%, 0 100%);
|
||||
|
||||
svg,
|
||||
&__ticks,
|
||||
&__bg,
|
||||
&__limit,
|
||||
&__value {
|
||||
@include abs();
|
||||
}
|
||||
|
||||
svg {
|
||||
path {
|
||||
transform-origin: center;
|
||||
}
|
||||
}
|
||||
|
||||
&__limit {
|
||||
&.c-limit-clip--90 {
|
||||
clip-path: polygon(0 0, 100% 0, 100% 100%);
|
||||
}
|
||||
|
||||
&.c-limit-clip--180 {
|
||||
clip-path: polygon(100% 0, 100% 100%, 0 100%);
|
||||
}
|
||||
|
||||
path {
|
||||
fill: rgba(orange, 0.4);
|
||||
}
|
||||
}
|
||||
|
||||
&__value {
|
||||
&.c-dial-clip--90 {
|
||||
clip-path: polygon(0 0, 50% 50%, 0 100%);
|
||||
}
|
||||
|
||||
&.c-dial-clip--180 {
|
||||
clip-path: polygon(0 0, 100% 0, 0 100%);
|
||||
}
|
||||
|
||||
path {
|
||||
fill: rgba(#fff, 0.8);
|
||||
}
|
||||
}
|
||||
|
||||
&__bg {
|
||||
g {
|
||||
fill: rgba(#fff, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "gaugeRadial",
|
||||
inject: ['openmct', 'domainObject', 'composition'],
|
||||
data: function () {
|
||||
let config = this.domainObject.configuration,
|
||||
rangeLow = config.min,
|
||||
rangeHigh = config.max,
|
||||
displayMinMax = config.displayMinMax,
|
||||
limit = config.limit,
|
||||
decimals = config.decimals;
|
||||
|
||||
return {
|
||||
rangeLow,
|
||||
rangeHigh,
|
||||
displayMinMax: displayMinMax.indexOf('Yes') !== -1,
|
||||
limit1: limit,
|
||||
decimals,
|
||||
curVal: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
round: function(val, decimals) {
|
||||
let precision = Math.pow(10, decimals);
|
||||
return Math.round(val * precision)/precision;
|
||||
},
|
||||
valToPercent: function(vValue) {
|
||||
// Don't let the current value exceed the high range, or the dial won't display right
|
||||
if (vValue >= this.rangeHigh) { return 100; }
|
||||
return ((vValue - this.rangeLow) / (this.rangeHigh - this.rangeLow)) * 100;
|
||||
},
|
||||
percentToDegrees: function(vPercent) {
|
||||
return this.round((vPercent/100)*270, 2);
|
||||
},
|
||||
updateValue(datum) {
|
||||
this.curVal = this.round(this.formats[this.valueKey].format(datum), this.decimals);
|
||||
},
|
||||
subscribe(domainObject) {
|
||||
this.metadata = this.openmct.telemetry.getMetadata(domainObject);
|
||||
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
|
||||
|
||||
this.valueKey = this
|
||||
.metadata
|
||||
.valuesForHints(['range'])[0].key;
|
||||
this.unsubscribe = this.openmct
|
||||
.telemetry
|
||||
.subscribe(domainObject, this.updateValue.bind(this), {});
|
||||
this.openmct
|
||||
.telemetry
|
||||
.request(domainObject, {strategy: 'latest'})
|
||||
.then((values) => values.forEach(this.updateValue));
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
degValue: function() {
|
||||
return this.percentToDegrees(this.valToPercent(this.curVal));
|
||||
},
|
||||
degLimit: function() {
|
||||
return this.percentToDegrees(this.valToPercent(this.limit1));
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.composition.on('add', this.subscribe);
|
||||
this.composition.load();
|
||||
},
|
||||
destroyed() {
|
||||
this.composition.off('add', this.subscribe);
|
||||
this.unsubscribe();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
71
src/plugins/gauge/gauge.js
Normal file
71
src/plugins/gauge/gauge.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* 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/gaugeRadial.vue',
|
||||
'vue'
|
||||
], function (
|
||||
GaugeComponent,
|
||||
Vue
|
||||
) {
|
||||
function Gauge(openmct) {
|
||||
return {
|
||||
key: 'gauge',
|
||||
name: 'Gauge',
|
||||
cssClass: 'icon-gauge',
|
||||
canView: function (domainObject) {
|
||||
return domainObject.type === 'gauge';
|
||||
},
|
||||
canEdit: function (domainObject) {
|
||||
return domainObject.type === 'gauge';
|
||||
},
|
||||
view: function (domainObject) {
|
||||
let component;
|
||||
|
||||
return {
|
||||
show: function (element) {
|
||||
component = new Vue({
|
||||
components: {
|
||||
GaugeComponent: GaugeComponent.default
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
domainObject,
|
||||
composition: openmct.composition.get(domainObject)
|
||||
},
|
||||
el: element,
|
||||
template: '<gauge-component></gauge-component>'
|
||||
});
|
||||
},
|
||||
destroy: function (element) {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
}
|
||||
};
|
||||
},
|
||||
priority: function () {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
return Gauge;
|
||||
});
|
||||
102
src/plugins/gauge/plugin.js
Normal file
102
src/plugins/gauge/plugin.js
Normal file
@@ -0,0 +1,102 @@
|
||||
/*****************************************************************************
|
||||
* 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([
|
||||
'./gauge'
|
||||
], function (
|
||||
Gauge
|
||||
) {
|
||||
return function plugin() {
|
||||
return function install(openmct) {
|
||||
openmct.objectViews.addProvider(new Gauge(openmct));
|
||||
|
||||
openmct.types.addType('gauge', {
|
||||
name: "Gauge",
|
||||
creatable: true,
|
||||
description: "Graphically visualize a telemetry element's current value between a minimum and maximum.",
|
||||
cssClass: 'icon-gauge',
|
||||
initialize(domainObject) {
|
||||
domainObject.composition = [];
|
||||
domainObject.configuration = {
|
||||
min: 0,
|
||||
max: 100,
|
||||
displayMinMax: 'Yes',
|
||||
limit: 90,
|
||||
decimals: 1
|
||||
};
|
||||
},
|
||||
form: [
|
||||
{
|
||||
name: "Minimum Value",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "min",
|
||||
property: [
|
||||
"configuration",
|
||||
"min"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Maximum Value",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "max",
|
||||
property: [
|
||||
"configuration",
|
||||
"max"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Display Min/Max",
|
||||
control: "textfield",
|
||||
cssClass: "l-input-sm",
|
||||
key: "displayMinMax",
|
||||
property: [
|
||||
"configuration",
|
||||
"displayMinMax"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Limit",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "min",
|
||||
property: [
|
||||
"configuration",
|
||||
"limit"
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Decimals",
|
||||
control: "numberfield",
|
||||
cssClass: "l-input-sm l-numeric",
|
||||
key: "decimals",
|
||||
property: [
|
||||
"configuration",
|
||||
"decimals"
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
};
|
||||
});
|
||||
@@ -23,6 +23,7 @@
|
||||
export default class GoToOriginalAction {
|
||||
constructor(openmct) {
|
||||
this.name = 'Go To Original';
|
||||
this.key = 'goToOriginal';
|
||||
this.description = 'Go to the original unlinked instance of this object';
|
||||
|
||||
this._openmct = openmct;
|
||||
|
||||
@@ -115,10 +115,22 @@
|
||||
width: (tickWidth + 30) + 'px'
|
||||
}">
|
||||
|
||||
<div class="gl-plot-label gl-plot-y-label">
|
||||
<div class="gl-plot-label gl-plot-y-label" ng-if="!yKeyOptions">
|
||||
{{ yAxis.get('label') }}
|
||||
</div>
|
||||
|
||||
<div class="gl-plot-label gl-plot-y-label" ng-if="yKeyOptions.length > 1 && series.length === 1">
|
||||
<select class="gl-plot-y-label__select"
|
||||
ng-model="yAxisLabel" ng-change="plot.toggleYAxisLabel(yAxisLabel, yKeyOptions, series[0])">
|
||||
<option ng-repeat="option in yKeyOptions"
|
||||
value="{{option.name}}"
|
||||
ng-selected="option.name === yAxisLabel">
|
||||
{{option.name}}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
|
||||
<mct-ticks axis="yAxis">
|
||||
<div ng-repeat="tick in ticks track by tick.text"
|
||||
class="gl-plot-tick gl-plot-y-tick-label"
|
||||
|
||||
@@ -377,6 +377,19 @@ define([
|
||||
delete this.unsubscribe;
|
||||
}
|
||||
this.fetch();
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears the plot series, unsubscribes and resubscribes
|
||||
* @public
|
||||
*/
|
||||
refresh: function () {
|
||||
this.reset();
|
||||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
delete this.unsubscribe;
|
||||
}
|
||||
this.fetch();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -93,6 +93,8 @@ define([
|
||||
this.$scope.series = this.config.series.models;
|
||||
this.$scope.legend = this.config.legend;
|
||||
|
||||
this.$scope.yAxisLabel = this.config.yAxis.get('label');
|
||||
|
||||
this.cursorGuideVertical = this.$element[0].querySelector('.js-cursor-guide--v');
|
||||
this.cursorGuideHorizontal = this.$element[0].querySelector('.js-cursor-guide--h');
|
||||
this.cursorGuide = false;
|
||||
@@ -103,9 +105,35 @@ define([
|
||||
this.listenTo(this.$scope, 'plot:tickWidth', this.onTickWidthChange, this);
|
||||
this.listenTo(this.$scope, 'plot:highlight:set', this.onPlotHighlightSet, this);
|
||||
this.listenTo(this.$scope, 'plot:reinitializeCanvas', this.initCanvas, this);
|
||||
|
||||
this.listenTo(this.config.xAxis, 'change:displayRange', this.onXAxisChange, this);
|
||||
this.listenTo(this.config.yAxis, 'change:displayRange', this.onYAxisChange, this);
|
||||
|
||||
this.setUpYAxisOptions();
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.setUpYAxisOptions = function () {
|
||||
if (this.$scope.series.length === 1) {
|
||||
let metadata = this.$scope.series[0].metadata;
|
||||
|
||||
this.$scope.yKeyOptions = metadata
|
||||
.valuesForHints(['range'])
|
||||
.map(function (o) {
|
||||
return {
|
||||
name: o.name,
|
||||
key: o.key
|
||||
};
|
||||
});
|
||||
|
||||
// set yAxisLabel if none is set yet
|
||||
if (this.$scope.yAxisLabel === 'none') {
|
||||
let yKey = this.$scope.series[0].model.yKey,
|
||||
yKeyModel = this.$scope.yKeyOptions.filter(o => o.key === yKey)[0];
|
||||
|
||||
this.$scope.yAxisLabel = yKeyModel.name;
|
||||
}
|
||||
} else {
|
||||
this.$scope.yKeyOptions = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.onXAxisChange = function (displayBounds) {
|
||||
@@ -493,5 +521,13 @@ define([
|
||||
this.cursorGuide = !this.cursorGuide;
|
||||
};
|
||||
|
||||
MCTPlotController.prototype.toggleYAxisLabel = function (label, options, series) {
|
||||
let yAxisObject = options.filter(o => o.name === label)[0];
|
||||
|
||||
if (yAxisObject) {
|
||||
series.emit('change:yKey', yAxisObject.key);
|
||||
}
|
||||
};
|
||||
|
||||
return MCTPlotController;
|
||||
});
|
||||
|
||||
@@ -63,8 +63,11 @@ 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);
|
||||
@@ -74,6 +77,7 @@ 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,
|
||||
@@ -263,6 +267,12 @@ define([
|
||||
});
|
||||
};
|
||||
|
||||
PlotController.prototype.clearData = function () {
|
||||
this.config.series.forEach(function (series) {
|
||||
series.refresh();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Export view as JPG.
|
||||
*/
|
||||
|
||||
@@ -43,7 +43,10 @@ define([
|
||||
'./LADTable/plugin',
|
||||
'./filters/plugin',
|
||||
'./objectMigration/plugin',
|
||||
'./goToOriginalAction/plugin'
|
||||
'./goToOriginalAction/plugin',
|
||||
'./clearData/plugin',
|
||||
'./gauge/plugin',
|
||||
'./bignumbers/plugin'
|
||||
], function (
|
||||
_,
|
||||
UTCTimeSystem,
|
||||
@@ -67,7 +70,10 @@ define([
|
||||
LADTable,
|
||||
Filters,
|
||||
ObjectMigration,
|
||||
GoToOriginalAction
|
||||
GoToOriginalAction,
|
||||
ClearData,
|
||||
Gauge,
|
||||
Bignumbers
|
||||
) {
|
||||
var bundleMap = {
|
||||
LocalStorage: 'platform/persistence/local',
|
||||
@@ -99,7 +105,6 @@ define([
|
||||
* to exclusively.
|
||||
*/
|
||||
plugins.AutoflowView = AutoflowPlugin;
|
||||
|
||||
plugins.Conductor = TimeConductorPlugin.default;
|
||||
|
||||
plugins.CouchDB = function (url) {
|
||||
@@ -166,6 +171,9 @@ define([
|
||||
plugins.Filters = Filters;
|
||||
plugins.ObjectMigration = ObjectMigration.default;
|
||||
plugins.GoToOriginalAction = GoToOriginalAction.default;
|
||||
plugins.ClearData = ClearData;
|
||||
plugins.Gauge = Gauge;
|
||||
plugins.Bignumbers = Bignumbers;
|
||||
|
||||
return plugins;
|
||||
});
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
export default class RemoveAction {
|
||||
constructor(openmct) {
|
||||
this.name = 'Remove';
|
||||
this.key = 'remove';
|
||||
this.description = 'Remove this object from its containing object.';
|
||||
this.cssClass = "icon-trash";
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ define([
|
||||
key: 'table-configuration',
|
||||
name: 'Telemetry Table Configuration',
|
||||
canView: function (selection) {
|
||||
if (selection.length === 0 || selection[0].length === 0) {
|
||||
if (selection.length !== 1 || selection[0].length === 0) {
|
||||
return false;
|
||||
}
|
||||
let object = selection[0][0].context.item;
|
||||
|
||||
@@ -26,6 +26,7 @@ define([
|
||||
'./collections/BoundedTableRowCollection',
|
||||
'./collections/FilteredTableRowCollection',
|
||||
'./TelemetryTableRow',
|
||||
'./TelemetryTableColumn',
|
||||
'./TelemetryTableConfiguration'
|
||||
], function (
|
||||
EventEmitter,
|
||||
@@ -33,6 +34,7 @@ define([
|
||||
BoundedTableRowCollection,
|
||||
FilteredTableRowCollection,
|
||||
TelemetryTableRow,
|
||||
TelemetryTableColumn,
|
||||
TelemetryTableConfiguration
|
||||
) {
|
||||
class TelemetryTable extends EventEmitter {
|
||||
@@ -47,6 +49,8 @@ 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);
|
||||
@@ -94,8 +98,6 @@ 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);
|
||||
@@ -105,7 +107,7 @@ define([
|
||||
}
|
||||
|
||||
addTelemetryObject(telemetryObject) {
|
||||
this.configuration.addColumnsForObject(telemetryObject, true);
|
||||
this.addColumnsForObject(telemetryObject, true);
|
||||
this.requestDataFor(telemetryObject);
|
||||
this.subscribeTo(telemetryObject);
|
||||
this.telemetryObjects.push(telemetryObject);
|
||||
@@ -144,14 +146,17 @@ define([
|
||||
let keyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||
let columnMap = this.getColumnMapForObject(keyString);
|
||||
let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
|
||||
|
||||
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
||||
this.boundedRows.add(telemetryRows);
|
||||
this.processHistoricalData(telemetryData, columnMap, keyString, limitEvaluator);
|
||||
}).finally(() => {
|
||||
this.decrementOutstandingRequests();
|
||||
});
|
||||
}
|
||||
|
||||
processHistoricalData(telemetryData, columnMap, keyString, limitEvaluator) {
|
||||
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
||||
this.boundedRows.add(telemetryRows);
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
@@ -191,6 +196,19 @@ 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);
|
||||
@@ -202,10 +220,17 @@ define([
|
||||
if (!this.telemetryObjects.includes(telemetryObject)) {
|
||||
return;
|
||||
}
|
||||
this.boundedRows.add(new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
||||
|
||||
if (!this.paused) {
|
||||
this.processRealtimeDatum(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');
|
||||
}
|
||||
@@ -234,12 +259,24 @@ 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);
|
||||
|
||||
if (this.filterObserver) {
|
||||
this.filterObserver();
|
||||
}
|
||||
|
||||
@@ -21,10 +21,11 @@
|
||||
*****************************************************************************/
|
||||
define(function () {
|
||||
class TelemetryTableColumn {
|
||||
constructor (openmct, metadatum) {
|
||||
constructor (openmct, metadatum, options = {selectable: false}) {
|
||||
this.metadatum = metadatum;
|
||||
this.formatter = openmct.telemetry.getValueFormatter(metadatum);
|
||||
this.titleValue = this.metadatum.name;
|
||||
this.selectable = options.selectable;
|
||||
}
|
||||
|
||||
getKey() {
|
||||
@@ -55,8 +56,7 @@ define(function () {
|
||||
return formattedValue;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
return TelemetryTableColumn;
|
||||
});
|
||||
|
||||
@@ -22,9 +22,8 @@
|
||||
|
||||
define([
|
||||
'lodash',
|
||||
'EventEmitter',
|
||||
'./TelemetryTableColumn'
|
||||
], function (_, EventEmitter, TelemetryTableColumn) {
|
||||
'EventEmitter'
|
||||
], function (_, EventEmitter) {
|
||||
|
||||
class TelemetryTableConfiguration extends EventEmitter {
|
||||
constructor(domainObject, openmct) {
|
||||
@@ -34,7 +33,6 @@ 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.
|
||||
@@ -48,6 +46,7 @@ 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;
|
||||
@@ -65,26 +64,18 @@ define([
|
||||
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
|
||||
this.domainObject = object;
|
||||
//Was it the configuration that changed?
|
||||
if (!_.eq(object.configuration, this.oldConfiguration)) {
|
||||
if (object.configuration !== undefined && !_.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);
|
||||
}
|
||||
}
|
||||
|
||||
addColumnsForAllObjects(objects) {
|
||||
objects.forEach(object => this.addColumnsForObject(object, false));
|
||||
}
|
||||
|
||||
addColumnsForObject(telemetryObject) {
|
||||
let metadataValues = this.openmct.telemetry.getMetadata(telemetryObject).values();
|
||||
addSingleColumnForObject(telemetryObject, column, position) {
|
||||
let objectKeyString = this.openmct.objects.makeKeyString(telemetryObject.identifier);
|
||||
this.columns[objectKeyString] = [];
|
||||
|
||||
metadataValues.forEach(metadatum => {
|
||||
let column = new TelemetryTableColumn(this.openmct, metadatum);
|
||||
this.columns[objectKeyString].push(column);
|
||||
});
|
||||
this.columns[objectKeyString] = this.columns[objectKeyString] || [];
|
||||
position = position || this.columns[objectKeyString].length;
|
||||
this.columns[objectKeyString].splice(position, 0, column);
|
||||
}
|
||||
|
||||
removeColumnsForObject(objectIdentifier) {
|
||||
|
||||
@@ -29,7 +29,7 @@ define([], function () {
|
||||
this.limitEvaluator = limitEvaluator;
|
||||
this.objectKeyString = objectKeyString;
|
||||
}
|
||||
|
||||
|
||||
getFormattedDatum(headers) {
|
||||
return Object.keys(headers).reduce((formattedDatum, columnKey) => {
|
||||
formattedDatum[columnKey] = this.getFormattedValue(columnKey);
|
||||
@@ -42,12 +42,19 @@ define([], function () {
|
||||
return column && column.getFormattedValue(this.datum[key]);
|
||||
}
|
||||
|
||||
getRowLimitClass() {
|
||||
if (!this.rowLimitClass) {
|
||||
getCellComponentName(key) {
|
||||
let column = this.columns[key];
|
||||
return column &&
|
||||
column.getCellComponentName &&
|
||||
column.getCellComponentName();
|
||||
}
|
||||
|
||||
getRowClass() {
|
||||
if (!this.rowClass) {
|
||||
let limitEvaluation = this.limitEvaluator.evaluate(this.datum);
|
||||
this.rowLimitClass = limitEvaluation && limitEvaluation.cssClass;
|
||||
this.rowClass = limitEvaluation && limitEvaluation.cssClass;
|
||||
}
|
||||
return this.rowLimitClass;
|
||||
return this.rowClass;
|
||||
}
|
||||
|
||||
getCellLimitClasses() {
|
||||
@@ -55,12 +62,16 @@ define([], function () {
|
||||
this.cellLimitClasses = Object.values(this.columns).reduce((alarmStateMap, column) => {
|
||||
let limitEvaluation = this.limitEvaluator.evaluate(this.datum, column.getMetadatum());
|
||||
alarmStateMap[column.getKey()] = limitEvaluation && limitEvaluation.cssClass;
|
||||
|
||||
|
||||
return alarmStateMap;
|
||||
}, {});
|
||||
}
|
||||
return this.cellLimitClasses;
|
||||
}
|
||||
|
||||
getContextMenuActions() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -78,4 +89,4 @@ define([], function () {
|
||||
}
|
||||
|
||||
return TelemetryTableRow;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
|
||||
define([
|
||||
'./components/table.vue',
|
||||
'../../exporters/CSVExporter',
|
||||
'./TelemetryTable',
|
||||
'vue'
|
||||
], function (
|
||||
TableComponent,
|
||||
CSVExporter,
|
||||
TelemetryTable,
|
||||
Vue
|
||||
) {
|
||||
@@ -50,8 +48,7 @@ define([
|
||||
canEdit(domainObject) {
|
||||
return domainObject.type === 'table';
|
||||
},
|
||||
view(domainObject) {
|
||||
let csvExporter = new CSVExporter.default();
|
||||
view(domainObject, isEditing, objectPath) {
|
||||
let table = new TelemetryTable(domainObject, openmct);
|
||||
let component;
|
||||
return {
|
||||
@@ -67,16 +64,19 @@ define([
|
||||
},
|
||||
provide: {
|
||||
openmct,
|
||||
csvExporter,
|
||||
table
|
||||
table,
|
||||
objectPath
|
||||
},
|
||||
el: element,
|
||||
template: '<table-component :isEditing="isEditing"></table-component>'
|
||||
template: '<table-component :isEditing="isEditing" :enableMarking="true"></table-component>'
|
||||
});
|
||||
},
|
||||
onEditModeChange(isEditing) {
|
||||
component.isEditing = isEditing;
|
||||
},
|
||||
onClearData() {
|
||||
table.refreshData();
|
||||
},
|
||||
destroy: function (element) {
|
||||
component.$destroy();
|
||||
component = undefined;
|
||||
|
||||
@@ -43,7 +43,8 @@ define(
|
||||
this.sortByTimeSystem(openmct.time.timeSystem());
|
||||
|
||||
this.lastBounds = openmct.time.bounds();
|
||||
openmct.time.on('bounds', this.bounds);
|
||||
|
||||
this.subscribeToBounds();
|
||||
}
|
||||
|
||||
addOne(item) {
|
||||
@@ -140,9 +141,17 @@ define(
|
||||
return this.parseTime(row.datum[this.sortOptions.key]);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
unsubscribeFromBounds() {
|
||||
this.openmct.time.off('bounds', this.bounds);
|
||||
}
|
||||
|
||||
subscribeToBounds() {
|
||||
this.openmct.time.on('bounds', this.bounds);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.unsubscribeFromBounds();
|
||||
}
|
||||
}
|
||||
return BoundedTableRowCollection;
|
||||
});
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
<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>
|
||||
71
src/plugins/telemetryTable/components/table-cell.vue
Normal file
71
src/plugins/telemetryTable/components/table-cell.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
/*****************************************************************************
|
||||
* 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 @click="selectCell($event.currentTarget, columnKey)" :title="formattedValue">{{formattedValue}}</td>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
props: {
|
||||
row: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
columnKey: {
|
||||
type: String,
|
||||
require: true
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
require: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectCell(element, columnKey) {
|
||||
if (this.isSelectable) {
|
||||
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.objectPath[0]
|
||||
}
|
||||
}], false);
|
||||
event.stopPropagation();
|
||||
}
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
formattedValue() {
|
||||
return this.row.getFormattedValue(this.columnKey);
|
||||
},
|
||||
isSelectable() {
|
||||
return this.row.columns[this.columnKey].selectable;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -23,6 +23,8 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import TelemetryTableColumn from '../TelemetryTableColumn';
|
||||
|
||||
export default {
|
||||
inject: ['tableConfiguration', 'openmct'],
|
||||
data() {
|
||||
@@ -43,7 +45,7 @@ export default {
|
||||
this.tableConfiguration.updateConfiguration(this.configuration);
|
||||
},
|
||||
addObject(domainObject) {
|
||||
this.tableConfiguration.addColumnsForObject(domainObject, true);
|
||||
this.addColumnsForObject(domainObject, true);
|
||||
this.updateHeaders(this.tableConfiguration.getAllHeaders());
|
||||
},
|
||||
removeObject(objectIdentifier) {
|
||||
@@ -56,6 +58,17 @@ 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() {
|
||||
@@ -65,7 +78,7 @@ export default {
|
||||
|
||||
compositionCollection.load()
|
||||
.then((composition) => {
|
||||
this.tableConfiguration.addColumnsForAllObjects(composition);
|
||||
this.addColumnsForAllObjects(composition);
|
||||
this.updateHeaders(this.tableConfiguration.getAllHeaders());
|
||||
|
||||
compositionCollection.on('add', this.addObject);
|
||||
|
||||
@@ -20,26 +20,55 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<tr :style="{ top: rowTop }" :class="rowLimitClass">
|
||||
<td v-for="(title, key) in headers"
|
||||
<tr :style="{ top: rowTop }"
|
||||
class="noselect"
|
||||
:class="[
|
||||
rowClass,
|
||||
{'is-selected': marked}
|
||||
]"
|
||||
v-on="listeners">
|
||||
<component 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]">{{formattedRow[key]}}</td>
|
||||
:class="[cellLimitClasses[key], selectableColumns[key] ? 'is-selectable' : '']"
|
||||
:objectPath="objectPath"
|
||||
:row="row">
|
||||
</component>
|
||||
</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 {
|
||||
inject: ['openmct', 'objectPath'],
|
||||
data: function () {
|
||||
return {
|
||||
rowTop: (this.rowOffset + this.rowIndex) * this.rowHeight + 'px',
|
||||
formattedRow: this.row.getFormattedDatum(this.headers),
|
||||
rowLimitClass: this.row.getRowLimitClass(),
|
||||
cellLimitClasses: this.row.getCellLimitClasses()
|
||||
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;
|
||||
}, {})
|
||||
}
|
||||
},
|
||||
props: {
|
||||
@@ -55,6 +84,10 @@ export default {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
objectPath: {
|
||||
type: Array,
|
||||
required: false
|
||||
},
|
||||
rowIndex: {
|
||||
type: Number,
|
||||
required: false,
|
||||
@@ -69,6 +102,11 @@ export default {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 0
|
||||
},
|
||||
marked: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -76,9 +114,54 @@ export default {
|
||||
this.rowTop = (rowOffset + this.rowIndex) * this.rowHeight + 'px';
|
||||
},
|
||||
formatRow: function (row) {
|
||||
this.formattedRow = row.getFormattedDatum(this.headers);
|
||||
this.rowLimitClass = row.getRowLimitClass();
|
||||
this.rowClass = row.getRowClass();
|
||||
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();
|
||||
}
|
||||
},
|
||||
showContextMenu: function (event) {
|
||||
event.preventDefault();
|
||||
|
||||
this.openmct.objects.get(this.row.objectKeyString).then((domainObject) => {
|
||||
let contextualObjectPath = this.objectPath.slice();
|
||||
contextualObjectPath.unshift(domainObject);
|
||||
|
||||
this.openmct.contextMenu._showContextMenuForObjectPath(contextualObjectPath, event.x, event.y, this.row.getContextMenuActions());
|
||||
});
|
||||
}
|
||||
},
|
||||
// TODO: use computed properties
|
||||
@@ -88,6 +171,22 @@ export default {
|
||||
handler: 'formatRow',
|
||||
deep: false
|
||||
}
|
||||
},
|
||||
components: {
|
||||
TableCell
|
||||
},
|
||||
computed: {
|
||||
listeners() {
|
||||
let listenersObject = {
|
||||
click: this.markRow
|
||||
}
|
||||
|
||||
if (this.row.getContextMenuActions().length) {
|
||||
listenersObject.contextmenu = this.showContextMenu;
|
||||
}
|
||||
|
||||
return listenersObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -20,92 +20,135 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<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">
|
||||
<div class="c-table-wrapper">
|
||||
<div class="c-table-control-bar c-control-bar">
|
||||
<button class="c-button icon-download labeled"
|
||||
v-on:click="exportAsCSV()"
|
||||
title="Export This View's Data">
|
||||
<span class="c-button__label">Export As CSV</span>
|
||||
v-if="allowExport"
|
||||
v-on:click="exportAllDataAsCSV()"
|
||||
title="Export This View's Data">
|
||||
<span class="c-button__label">Export Table Data</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 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>
|
||||
|
||||
<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"
|
||||
:objectPath="objectPath"
|
||||
: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>
|
||||
</table>
|
||||
<telemetry-filter-indicator></telemetry-filter-indicator>
|
||||
</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">
|
||||
</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>
|
||||
</div><!-- closes c-table-wrapper -->
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@@ -131,7 +174,7 @@
|
||||
display: block;
|
||||
flex: 1 0 auto;
|
||||
width: 100px;
|
||||
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
|
||||
vertical-align: middle; // This is crucial to hiding 4px height injected by browser by default
|
||||
}
|
||||
|
||||
td {
|
||||
@@ -216,6 +259,10 @@
|
||||
align-items: stretch;
|
||||
position: absolute;
|
||||
height: 18px; // Needed when a row has empty values in its cells
|
||||
|
||||
&.is-selected {
|
||||
background-color: $colorSelectedBg;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
@@ -266,6 +313,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.paused {
|
||||
border: 1px solid #ff9900;
|
||||
}
|
||||
|
||||
/******************************* LEGACY */
|
||||
.s-status-taking-snapshot,
|
||||
.overlay.snapshot {
|
||||
@@ -279,6 +330,8 @@
|
||||
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;
|
||||
@@ -293,13 +346,30 @@ export default {
|
||||
components: {
|
||||
TelemetryTableRow,
|
||||
TableColumnHeader,
|
||||
search
|
||||
search,
|
||||
TelemetryFilterIndicator
|
||||
},
|
||||
inject: ['table', 'openmct', 'csvExporter'],
|
||||
inject: ['table', 'openmct', 'objectPath'],
|
||||
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() {
|
||||
@@ -328,7 +398,10 @@ export default {
|
||||
dropOffsetLeft: undefined,
|
||||
isDropTargetActive: false,
|
||||
isAutosizeEnabled: configuration.autosize,
|
||||
scrollW: 0
|
||||
scrollW: 0,
|
||||
markCounter: 0,
|
||||
paused: false,
|
||||
markedRows: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -514,15 +587,27 @@ export default {
|
||||
// which causes subsequent scroll to use an out of date height.
|
||||
this.contentTable.style.height = this.totalHeight + 'px';
|
||||
},
|
||||
exportAsCSV() {
|
||||
exportAsCSV(data) {
|
||||
const headerKeys = Object.keys(this.headers);
|
||||
const justTheData = this.table.filteredRows.getRows()
|
||||
.map(row => row.getFormattedDatum(this.headers));
|
||||
this.csvExporter.export(justTheData, {
|
||||
|
||||
this.csvExporter.export(data, {
|
||||
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;
|
||||
},
|
||||
@@ -611,12 +696,114 @@ 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);
|
||||
@@ -624,6 +811,7 @@ 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);
|
||||
@@ -649,6 +837,7 @@ 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);
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<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>
|
||||
@@ -167,6 +167,7 @@ export default {
|
||||
this.xAxis.scale(this.xScale);
|
||||
this.xAxis.tickFormat(utcMultiTimeFormat);
|
||||
this.axisElement.call(this.xAxis);
|
||||
this.setScale();
|
||||
},
|
||||
getActiveFormatter() {
|
||||
let timeSystem = this.openmct.time.timeSystem();
|
||||
|
||||
@@ -60,7 +60,6 @@ export default {
|
||||
.filter(menuOption => menuOption.clock === (clock && clock.key))
|
||||
.map(menuOption => JSON.parse(JSON.stringify(this.openmct.time.timeSystems.get(menuOption.timeSystem))));
|
||||
},
|
||||
|
||||
setTimeSystemFromView(timeSystem) {
|
||||
if (timeSystem.key !== this.selectedTimeSystem.key) {
|
||||
let activeClock = this.openmct.time.clock();
|
||||
@@ -69,7 +68,15 @@ export default {
|
||||
timeSystem: timeSystem.key
|
||||
});
|
||||
if (activeClock === undefined) {
|
||||
this.openmct.time.timeSystem(timeSystem.key, configuration.bounds);
|
||||
let bounds;
|
||||
|
||||
if (this.selectedTimeSystem.isUTCBased && timeSystem.isUTCBased) {
|
||||
bounds = this.openmct.time.bounds();
|
||||
} else {
|
||||
bounds = configuration.bounds;
|
||||
}
|
||||
|
||||
this.openmct.time.timeSystem(timeSystem.key, bounds);
|
||||
} else {
|
||||
this.openmct.time.timeSystem(timeSystem.key);
|
||||
this.openmct.time.clockOffsets(configuration.clockOffsets);
|
||||
|
||||
@@ -70,9 +70,6 @@ $colorBodyFgEm: #fff;
|
||||
$colorGenBg: #222;
|
||||
$colorHeadBg: #262626;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
$colorStatusBarBg: $colorHeadBg;
|
||||
$colorStatusBarFg: $colorBodyFg;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeyFg: #fff;
|
||||
$colorKeyHov: #26d8ff;
|
||||
@@ -101,10 +98,12 @@ $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: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningHi: #ff0000;
|
||||
$colorWarningHiFg: #ffdad0;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
@@ -115,6 +114,8 @@ $colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
$colorFilterBg: #44449c;
|
||||
$colorFilterFg: #8984e9;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@@ -210,6 +211,10 @@ $btnStdH: 24px;
|
||||
$colorCursorGuide: rgba(white, 0.6);
|
||||
$shdwCursorGuide: rgba(black, 0.4) 0 0 2px;
|
||||
$colorLocalControlOvrBg: rgba($colorBodyBg, 0.8);
|
||||
$colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due to usage of SVG bg in selects
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||
@@ -277,6 +282,11 @@ $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%);
|
||||
@@ -419,7 +429,3 @@ $createBtnTextTransform: uppercase;
|
||||
background: linear-gradient(pullForward($c, 5%), $c);
|
||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||
}
|
||||
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||
}
|
||||
|
||||
@@ -36,9 +36,10 @@ $bodyFont: 'Chakra Petch', sans-serif;
|
||||
|
||||
@mixin headerFont($size: 1em) {
|
||||
font-family: $headerFont;
|
||||
font-size: $size * 0.8; // This font is comparatively large, so reduce it a bit
|
||||
font-size: $size;
|
||||
line-height: $size;
|
||||
text-transform: uppercase;
|
||||
word-spacing: 0.25em;
|
||||
word-spacing: 0.4em;
|
||||
}
|
||||
|
||||
@mixin bodyFont($size: 1em) {
|
||||
@@ -68,14 +69,14 @@ $shdwBtns: rgba(black, 0.2) 0 1px 2px;
|
||||
$shdwBtnsOverlay: rgba(black, 0.5) 0 1px 5px;
|
||||
|
||||
// Base colors
|
||||
$colorBodyBg: #393939;
|
||||
$colorBodyBg: #000000;
|
||||
$colorBodyFg: #ccc;
|
||||
$colorBodyFgEm: #fff;
|
||||
$colorGenBg: #222;
|
||||
$colorHeadBg: #262626;
|
||||
$colorHeadBg: transparent;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
$colorStatusBarBg: $colorHeadBg;
|
||||
$colorStatusBarFg: $colorBodyFg;
|
||||
$colorStatusBarFg: rgba(white, 0.5);
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeyFg: #fff;
|
||||
@@ -105,10 +106,12 @@ $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: #990000;
|
||||
$colorWarningHiFg: #FF9594;
|
||||
$colorWarningHi: #ff0000;
|
||||
$colorWarningHiFg: #ffdad0;
|
||||
$colorWarningLo: #ff9900;
|
||||
$colorWarningLoFg: #523400;
|
||||
$colorDiagnostic: #a4b442;
|
||||
@@ -119,6 +122,8 @@ $colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
$colorFilterBg: #44449c;
|
||||
$colorFilterFg: #8984e9;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@@ -184,7 +189,7 @@ $colorIconAliasForKeyFilter: #aaa;
|
||||
$colorTabsHolderBg: rgba(black, 0.2);
|
||||
|
||||
// Buttons and Controls
|
||||
$colorBtnBg: pullForward($colorBodyBg, 10%);
|
||||
$colorBtnBg: pullForward($colorBodyBg, 30%);
|
||||
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
|
||||
$colorBtnFg: pullForward($colorBodyFg, 10%);
|
||||
$colorBtnReverseFg: pullForward($colorBtnFg, 10%);
|
||||
@@ -214,6 +219,10 @@ $btnStdH: 24px;
|
||||
$colorCursorGuide: rgba(white, 0.6);
|
||||
$shdwCursorGuide: rgba(black, 0.4) 0 0 2px;
|
||||
$colorLocalControlOvrBg: rgba($colorBodyBg, 0.8);
|
||||
$colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due to usage of SVG bg in selects
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||
$shdwSelect: rgba(black, 0.5) 0 0.5px 3px;
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||
@@ -281,6 +290,11 @@ $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%);
|
||||
@@ -424,10 +438,6 @@ $createBtnTextTransform: uppercase;
|
||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||
}
|
||||
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||
}
|
||||
|
||||
/**************************************************** OVERRIDES */
|
||||
.c-frame {
|
||||
&:not(.no-frame) {
|
||||
|
||||
@@ -42,6 +42,31 @@ $bodyFont: $heroFont;
|
||||
font-size: $size;
|
||||
}
|
||||
|
||||
// FONTS
|
||||
@import url('https://fonts.googleapis.com/css?family=Chakra+Petch:400,600,700|Michroma|Teko:400,700');
|
||||
|
||||
$heroFont: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
$headerFont: $heroFont;
|
||||
$bodyFont: $heroFont;
|
||||
|
||||
@mixin heroFont($size: 1em) {
|
||||
$mult: 1;
|
||||
font-family: $heroFont;
|
||||
font-size: $size * $mult;
|
||||
}
|
||||
|
||||
@mixin headerFont($size: 1em) {
|
||||
$mult: 1;
|
||||
font-family: $headerFont;
|
||||
font-size: $size * $mult;
|
||||
}
|
||||
|
||||
@mixin bodyFont($size: 1em) {
|
||||
$mult: 1;
|
||||
font-family: $bodyFont;
|
||||
font-size: $size * $mult;
|
||||
}
|
||||
|
||||
// Functions
|
||||
@function buttonBg($c: $colorBtnBg) {
|
||||
@return $c;
|
||||
@@ -70,9 +95,6 @@ $colorBodyFgEm: #333;
|
||||
$colorGenBg: #fff;
|
||||
$colorHeadBg: #eee;
|
||||
$colorHeadFg: $colorBodyFg;
|
||||
$colorStatusBarBg: #000;
|
||||
$colorStatusBarFg: #999;
|
||||
$colorStatusBarFgHov: #aaa;
|
||||
$colorKey: #0099cc;
|
||||
$colorKeyFg: #fff;
|
||||
$colorKeyHov: #00c0f6;
|
||||
@@ -101,6 +123,8 @@ $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;
|
||||
@@ -115,6 +139,8 @@ $colorInfo: #2294a2;
|
||||
$colorInfoFg: #fff;
|
||||
$colorOk: #33cc33;
|
||||
$colorOkFg: #fff;
|
||||
$colorFilterBg: #a29fe2;
|
||||
$colorFilterFg: #fff;
|
||||
|
||||
// States
|
||||
$colorPausedBg: #ff9900;
|
||||
@@ -210,6 +236,10 @@ $btnStdH: 24px;
|
||||
$colorCursorGuide: rgba(black, 0.6);
|
||||
$shdwCursorGuide: rgba(white, 0.4) 0 0 2px;
|
||||
$colorLocalControlOvrBg: rgba($colorBodyFg, 0.8);
|
||||
$colorSelectBg: $colorBtnBg; // This must be a solid color, not a gradient, due to usage of SVG bg in selects
|
||||
$colorSelectFg: $colorBtnFg;
|
||||
$colorSelectArw: lighten($colorBtnBg, 20%);
|
||||
$shdwSelect: none;
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: pushBack($colorBodyBg, 10%);
|
||||
@@ -277,6 +307,11 @@ $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%);
|
||||
@@ -418,7 +453,3 @@ $createBtnTextTransform: uppercase;
|
||||
@mixin themedButton($c: $colorBtnBg) {
|
||||
background: $c;
|
||||
}
|
||||
|
||||
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||
@include cSelect($bg, $fg, lighten($bg, 20%), none);
|
||||
}
|
||||
|
||||
@@ -141,6 +141,8 @@ $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';
|
||||
|
||||
@@ -49,6 +49,21 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
&[class*='__collapse-button'] {
|
||||
box-shadow: none;
|
||||
background: $splitterBtnColorBg;
|
||||
color: $splitterBtnColorFg;
|
||||
border-radius: $smallCr;
|
||||
font-size: 6px;
|
||||
line-height: 90%;
|
||||
padding: 3px 15px;
|
||||
|
||||
@include hover() {
|
||||
background: $colorBtnBgHov;
|
||||
color: $colorBtnFgHov;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background: $colorBtnActiveBg;
|
||||
color: $colorBtnActiveFg;
|
||||
@@ -60,23 +75,23 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
/********* Icon Buttons */
|
||||
/********* Icon Buttons and Links */
|
||||
.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();
|
||||
|
||||
&--menu {
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.7em;
|
||||
margin-left: floor($interiorMarginSm * 0.8);
|
||||
opacity: 0.5;
|
||||
}
|
||||
@include hasMenu();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +141,7 @@ button {
|
||||
|
||||
/******************************************************** DISCLOSURE CONTROLS */
|
||||
/********* Disclosure Button */
|
||||
// Provides a downward arrow icon that when clicked displays a context menu
|
||||
// Provides a downward arrow icon that when clicked displays additional options and/or info.
|
||||
// Always placed AFTER an element
|
||||
.c-disclosure-button {
|
||||
@include cClickIcon();
|
||||
@@ -264,7 +279,10 @@ input[type=number]::-webkit-outer-spin-button {
|
||||
// SELECTS
|
||||
select {
|
||||
@include appearanceNone();
|
||||
@include themedSelect();
|
||||
background-color: $colorSelectBg;
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10'%3e%3cpath fill='%23#{svgColorFromHex($colorSelectArw)}' d='M5 5l5-5H0z'/%3e%3c/svg%3e");
|
||||
color: $colorSelectFg;
|
||||
box-shadow: $shdwSelect;
|
||||
background-repeat: no-repeat, no-repeat;
|
||||
background-position: right .4em top 80%, 0 0;
|
||||
border: none;
|
||||
@@ -585,15 +603,15 @@ select {
|
||||
margin-right: $m;
|
||||
}
|
||||
|
||||
.c-separator {
|
||||
@include cToolbarSeparator();
|
||||
}
|
||||
|
||||
.c-toolbar {
|
||||
> * + * {
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
&__button {
|
||||
|
||||
}
|
||||
|
||||
&__separator {
|
||||
@include cToolbarSeparator();
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@
|
||||
}
|
||||
|
||||
@font-face {
|
||||
// Use https://icomoon.io/app with icomoon-project-openmct-symbols-12px.json to generate font files
|
||||
// Use https://icomoon.io/app with icomoon-project-Open-MCT-Symbols-12px.json to generate font files
|
||||
font-family: 'symbolsfont-12px';
|
||||
src: url('./fonts/openmct-symbols-12px.woff') format('woff'),
|
||||
url('./fonts/openmct-symbols-12px.ttf') format('truetype');
|
||||
src: url('./fonts/Open-MCT-Symbols-12px.woff') format('woff'),
|
||||
url('./fonts/Open-MCT-Symbols-12px.ttf') format('truetype');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@@ -77,6 +77,8 @@
|
||||
.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); }
|
||||
@@ -164,6 +166,8 @@
|
||||
|
||||
/************************** 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'); }
|
||||
|
||||
@@ -161,8 +161,7 @@ mct-plot {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
&.gl-plot-y-label,
|
||||
&.l-plot-y-label {
|
||||
&.gl-plot-y-label {
|
||||
$x: -50%;
|
||||
$r: -90deg;
|
||||
transform-origin: 50% 0;
|
||||
@@ -172,6 +171,12 @@ mct-plot {
|
||||
left: 0;
|
||||
top: 50%;
|
||||
white-space: nowrap;
|
||||
|
||||
select {
|
||||
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10'%3e%3cpath fill='%23#{svgColorFromHex($colorSelectArw)}' d='M0 5l5 5V0L0 5z'/%3e%3c/svg%3e");
|
||||
background-position: left .4em top 50%, 0 0;
|
||||
padding: 1px $interiorMargin 1px 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -782,126 +782,6 @@ mct-indicators mct-include {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.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;
|
||||
bottom: 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;
|
||||
top: 100%;
|
||||
@include triangle('down', $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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
// 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;
|
||||
|
||||
@@ -50,14 +50,14 @@
|
||||
}
|
||||
|
||||
/************************** EFFECTS */
|
||||
@mixin pulse($animName: pulse, $dur: 500ms, $iteration: infinite, $opacity0: 0.5, $opacity100: 1) {
|
||||
@keyframes pulse {
|
||||
0% { opacity: $opacity0; }
|
||||
100% { opacity: $opacity100; }
|
||||
@mixin pulse($animName: 'pulse', $dur: 500ms, $iteration: infinite, $prop: opacity, $val0: 0, $val100: 1, $direction: alternate) {
|
||||
@keyframes #{$animName} {
|
||||
0% { #{$prop}: $val0; }
|
||||
100% { #{$prop}: $val100; }
|
||||
}
|
||||
animation-name: $animName;
|
||||
animation-duration: $dur;
|
||||
animation-direction: alternate;
|
||||
animation-direction: $direction;
|
||||
animation-iteration-count: $iteration;
|
||||
animation-timing-function: ease-in-out;
|
||||
}
|
||||
@@ -420,20 +420,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cClickIconButton() {
|
||||
// A clickable element that just includes the icon
|
||||
// Background is displayed on hover
|
||||
// Padding is included to facilitate a bigger hit area
|
||||
// Make the icon bigger relative to its container
|
||||
@mixin cClickIconButtonLayout() {
|
||||
$pLR: 4px;
|
||||
$pTB: 4px;
|
||||
|
||||
@include cControl();
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
transition: $transOut;
|
||||
border-radius: $controlCr;
|
||||
padding: $pTB $pLR;
|
||||
|
||||
&:before,
|
||||
@@ -442,6 +431,20 @@
|
||||
// Needed for c-togglebutton.
|
||||
font-size: 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cClickIconButton() {
|
||||
// A clickable element that just includes the icon
|
||||
// Background is displayed on hover
|
||||
// Padding is included to facilitate a bigger hit area
|
||||
// Make the icon bigger relative to its container
|
||||
@include cControl();
|
||||
@include cClickIconButtonLayout();
|
||||
background: none;
|
||||
box-shadow: none;
|
||||
cursor: pointer;
|
||||
transition: $transOut;
|
||||
border-radius: $controlCr;
|
||||
|
||||
@include hover() {
|
||||
transition: $transIn;
|
||||
@@ -478,6 +481,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
@mixin hasMenu() {
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.7em;
|
||||
margin-left: floor($interiorMarginSm * 0.8);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cSelect($bg, $fg, $arwClr, $shdw) {
|
||||
$svgArwClr: str-slice(inspect($arwClr), 2, str-length(inspect($arwClr))); // Remove initial # in color value
|
||||
background: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10'%3e%3cpath fill='%23#{$svgArwClr}' d='M5 5l5-5H0z'/%3e%3c/svg%3e"), $bg;
|
||||
@@ -572,6 +585,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
@function svgColorFromHex($hexColor) {
|
||||
// Remove initial # in color value
|
||||
@return str-slice(inspect($hexColor), 2, str-length(inspect($hexColor)));
|
||||
}
|
||||
|
||||
@mixin test($c: deeppink, $a: 0.3) {
|
||||
background: rgba($c, $a) !important;
|
||||
background-color: rgba($c, $a) !important;
|
||||
|
||||
447
src/styles-new/_movie-maelstrom.scss
Normal file
447
src/styles-new/_movie-maelstrom.scss
Normal file
@@ -0,0 +1,447 @@
|
||||
/**************************************************** CONSTANTS, MIXINS */
|
||||
$bgKey: #222632;
|
||||
$redKeyBg: #990000;
|
||||
$redKeyBrdr: #ff0000;
|
||||
$redKeyFg: rgba(white, 0.8);
|
||||
$ylwKeyBg: #cc6b36;
|
||||
$ylwKeyBrdr: #ffbf1a;
|
||||
$ylwKeyFg: rgba(white, 0.8);
|
||||
|
||||
@mixin widgetOk() {
|
||||
background-color: #bbb !important;
|
||||
border-color: #fff !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
@mixin widgetRed() {
|
||||
background-color: $redKeyBg !important;
|
||||
border-color: $redKeyBrdr !important;
|
||||
color: $redKeyFg !important;
|
||||
}
|
||||
|
||||
@mixin widgetYellow() {
|
||||
$c: $ylwKeyFg;
|
||||
background-color: $ylwKeyBg !important;
|
||||
border-color: $ylwKeyBrdr !important;
|
||||
color: $ylwKeyFg !important;
|
||||
}
|
||||
|
||||
/**************************************************** OVERRIDES */
|
||||
body {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.c-telemetry-view__value {
|
||||
justify-content: center;
|
||||
&[class*='is-limit'] {
|
||||
background: transparent !important;
|
||||
color: inherit !important;
|
||||
&:before { display: none; }
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************** CONVENIENCE */
|
||||
.u-inspectable[s-selected] {
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
.c-table.c-telemetry-table {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
.widget-rule-content .t-rule-message-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/**************************************************** TIME CONDUCTOR */
|
||||
.c-conductor {
|
||||
&__controls {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.c-conductor__controls { display: flex !important; }
|
||||
}
|
||||
|
||||
[class*='__label'] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__end-fixed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__end-delta {
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
background: url('../ui/layout/assets/images/logo-app.svg') center no-repeat;
|
||||
background-size: contain;
|
||||
width: 100px;
|
||||
height: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-input {
|
||||
input {
|
||||
&.c-input--datetime,
|
||||
&.c-input--hrs-min-sec {
|
||||
color: $colorTime;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
&.c-input--hrs-min-sec {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************** MAIN LAYOUT */
|
||||
.l-shell {
|
||||
&:not(.is-editing) {
|
||||
.l-shell__head,
|
||||
.l-shell__main-view-browse-bar {
|
||||
background: none !important;
|
||||
height: $interiorMargin;
|
||||
overflow: hidden;
|
||||
padding: 0 !important;
|
||||
position: absolute;
|
||||
width: 30%;
|
||||
z-index: 100;
|
||||
|
||||
* { opacity: 0; }
|
||||
|
||||
&:hover {
|
||||
background: #666 !important;
|
||||
height: auto;
|
||||
overflow: visible;
|
||||
padding: $interiorMargin !important;
|
||||
|
||||
* { opacity: 1; }
|
||||
}
|
||||
}
|
||||
|
||||
.l-shell__pane-main .l-pane__contents > * + * {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.l-shell__main-container {
|
||||
margin-top: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.l-shell__main-view-browse-bar {
|
||||
top: -3px; right: 0;
|
||||
}
|
||||
|
||||
&__main > .l-pane {
|
||||
padding-left: $interiorMargin !important;
|
||||
padding-right: $interiorMargin !important;
|
||||
}
|
||||
|
||||
&__status { display: none !important; }
|
||||
}
|
||||
|
||||
.l-pane {
|
||||
&__contents {
|
||||
overflow: visible !important;
|
||||
}
|
||||
|
||||
&--collapsed {
|
||||
$d: 5px;
|
||||
flex-basis: $d !important;
|
||||
min-width: $d !important;
|
||||
min-height: $d !important;
|
||||
|
||||
.l-pane__label {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.l-pane__collapse-button {
|
||||
&:before { display: none !important; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************** STYLING BY TITLE */
|
||||
*[title*='font-euro'] {
|
||||
@include headerFont();
|
||||
}
|
||||
|
||||
*[title*='key-widget'] {
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
*[title*='alert-red'] {
|
||||
.c-sw__icon {
|
||||
color: red !important;
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='alert-yellow'] {
|
||||
.c-sw__icon {
|
||||
color: $ylwKeyBg !important;
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='widget-ok'] {
|
||||
@include widgetOk();
|
||||
}
|
||||
|
||||
*[title*='widget-yellow'] {
|
||||
@include widgetYellow();
|
||||
}
|
||||
|
||||
*[title*='widget-red'] {
|
||||
@include widgetRed();
|
||||
}
|
||||
|
||||
*[title*='pulse-slow'] {
|
||||
@include pulse($animName: pulseSlow, $dur: 1000ms, $prop: filter, $val0: brightness(1.2), $val100: brightness(0.6), $direction: normal);
|
||||
.c-sw__icon {
|
||||
@include pulse($animName: pulseWarningIcon, $dur: 500ms, $prop: opacity, $val0: 0.1, $val100: 1, $direction: normal);
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='pulse-fast'] {
|
||||
@include pulse($animName: pulseSlow, $dur: 250ms, $prop: filter, $val0: brightness(1.5), $val100: brightness(0.9), $direction: normal);
|
||||
}
|
||||
|
||||
*[title*='pulse-warning'] {
|
||||
@include pulse($animName: pulseWarning, $dur: 1500ms, $prop: filter, $val0: brightness(1.2), $val100: brightness(0.7), $direction: normal);
|
||||
}
|
||||
|
||||
*[title*='Bg Widget'] {
|
||||
// Widgets that provide a flashing red bg for components
|
||||
.c-summary-widget {
|
||||
$b: 5px;
|
||||
border: none !important;
|
||||
border-radius: $b * 4;
|
||||
&[title*='widget-yellow'] {
|
||||
opacity: 0.3;
|
||||
box-shadow: $ylwKeyBg 0px 0px $b $b;
|
||||
}
|
||||
|
||||
&[title*='widget-red'] {
|
||||
opacity: 0.4;
|
||||
box-shadow: $redKeyBg 0px 0px $b $b;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**************************************************** SECTIONS */
|
||||
/************* SYS OVW WIDGETS */
|
||||
*[title*='Sys Ovw'] {
|
||||
*[title*='Widget'] {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
*[title*='sys-ok'] {
|
||||
@include widgetOk();
|
||||
}
|
||||
|
||||
*[title*='post-ring'] {
|
||||
@include widgetRed();
|
||||
}
|
||||
}
|
||||
|
||||
/************* ATTITUDE */
|
||||
*[title*='Attitude'] {
|
||||
*[title*='RPY'] {
|
||||
background: black;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
|
||||
.l-control-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.l-view-section {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.gl-plot-axis-area.gl-plot-y {
|
||||
width: 22px !important;
|
||||
}
|
||||
|
||||
.gl-plot-wrapper-display-area-and-x-axis {
|
||||
left: 24px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************* VELOCITY COMPONENT */
|
||||
*[title*='-not-attained'] {
|
||||
@include widgetRed();
|
||||
}
|
||||
|
||||
/************* ACCELERATION COMPONENT */
|
||||
|
||||
/************* BOOST PHASE WIDGETS */
|
||||
*[title*='boost-phase-widget'] {
|
||||
.c-summary-widget {
|
||||
border-width: 2px;
|
||||
padding: 5px 0;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='boost-phase-widget-left'] {
|
||||
.c-summary-widget {
|
||||
$c: #999;
|
||||
align-items: start;
|
||||
background: rgba($c, 0.1) !important;
|
||||
border-left: none;
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
top: 25px; right: 0; bottom: 3%; left: 40%;
|
||||
}
|
||||
|
||||
&:before {
|
||||
@include bgStripes($c: $c, $a: 0.1, $bgsize: 20px, $angle: 0deg);
|
||||
}
|
||||
|
||||
&:after {
|
||||
@include bgStripes($c: $c, $a: 0.1, $bgsize: 63px, $angle: 0deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='boost-phase-widget-right'] {
|
||||
.c-summary-widget {
|
||||
$c: #555;
|
||||
border-right: none;
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
|
||||
&:before {
|
||||
//background: deeppink;
|
||||
@include bgTicks($c: $c, $repeatDir: 'y');
|
||||
background-size: 100% 45px;
|
||||
top: 0px; right: 0; bottom: 0; left: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*[title*='Boost Phase Ring Widgets'] {
|
||||
*[title*='Ring Widget'] {
|
||||
//filter: saturate(0.7);
|
||||
}
|
||||
|
||||
*[title*='ring-ok'] {
|
||||
@include widgetOk();
|
||||
}
|
||||
|
||||
*[title*='bad-ring'] {
|
||||
@include widgetRed();
|
||||
}
|
||||
|
||||
*[title*='post-ring'] {
|
||||
@include widgetYellow();
|
||||
}
|
||||
}
|
||||
|
||||
/************* BOTTOM SYSTEM WIDGETS */
|
||||
*[title*='system-widget'] {
|
||||
background: $bgKey !important;
|
||||
border-width: 2px !important;
|
||||
justify-content: left !important;
|
||||
|
||||
.c-sw__icon {
|
||||
$m: $interiorMarginSm;
|
||||
position: absolute;
|
||||
bottom: $m;
|
||||
right: $m;
|
||||
}
|
||||
}
|
||||
|
||||
*[title*="Bottom System Widgets"] {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
*[title*='system-widget--hero'] {
|
||||
// Current "tab" in interface
|
||||
border-top-left-radius: 0;
|
||||
border-top-right-radius: 0;
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
*[title*='system-widget--subtle'] {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
/**************************************************** INDIVIDUAL ELEMENTS */
|
||||
/************* PASSENGER NOTICE */
|
||||
*[title*='passenger-notice'] {
|
||||
font-size: 1.4em;
|
||||
.c-sw__icon {
|
||||
font-size: 2.1em;
|
||||
margin-right: $interiorMarginLg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
*[title*='pulse-passenger-notice--nominal'] {
|
||||
@include pulse($animName: pulseNominal, $dur: 1000ms, $prop: filter, $val0: brightness(1.4), $val100:brightness(1.0), $direction: alternate);
|
||||
}
|
||||
|
||||
*[title*='pulse-passenger-notice--warning'] {
|
||||
@include pulse($animName: pulseWarning, $dur: 750ms, $prop: background-color, $val0: #aa0000, $val100: #340000, $direction: normal);
|
||||
}
|
||||
|
||||
*[title*='Main Console'] {
|
||||
$r: $basicCr;
|
||||
background: $bgKey;
|
||||
border-radius: $r;
|
||||
border-bottom: 2px solid rgb(102,102,102);
|
||||
}
|
||||
|
||||
*[title*='Event Time Str'] {
|
||||
@include heroFont(1.2em);
|
||||
line-height: .8em;
|
||||
}
|
||||
|
||||
|
||||
*[title*="Sys Ovw LAD Table"] {
|
||||
.c-lad-table {
|
||||
tr {
|
||||
background-color: black;
|
||||
color: rgba(white, 0.3);
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
height: 41px;
|
||||
border-radius: 5px;
|
||||
font-size: 0.75em;
|
||||
margin-bottom: 4px;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
thead,
|
||||
tr td:nth-child(1),
|
||||
tr td:nth-child(2) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
td {
|
||||
display: block;
|
||||
width: auto;
|
||||
white-space: normal;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
}
|
||||
|
||||
@mixin indicatorStatusColors($c) {
|
||||
&:before, .count {
|
||||
&:before, .c-indicator__count {
|
||||
color: $c;
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ tr {
|
||||
.s-status-icon-ok:before { content: $glyph-icon-check; }
|
||||
|
||||
/*************************************************** INDICATOR COLORING */
|
||||
.ls-indicator {
|
||||
.c-indicator {
|
||||
&.s-status-info {
|
||||
@include indicatorStatusColors($colorInfo);
|
||||
}
|
||||
@@ -159,3 +159,16 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -76,23 +76,43 @@ 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;
|
||||
|
||||
@@ -34,3 +34,5 @@
|
||||
@import "legacy";
|
||||
@import "legacy-plots";
|
||||
@import "legacy-messages";
|
||||
@import "theme-maelstrom";
|
||||
@import "movie-maelstrom";
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "openmct-symbols-12px",
|
||||
"name": "Open MCT Symbols 12px",
|
||||
"lastOpened": 0,
|
||||
"created": 1527031065005
|
||||
"created": 1561483556329
|
||||
},
|
||||
"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,
|
||||
@@ -21,7 +37,7 @@
|
||||
"name": "icon12-grippy",
|
||||
"prevSize": 12,
|
||||
"code": 59697,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 10,
|
||||
@@ -29,7 +45,7 @@
|
||||
"name": "icon12-list-view",
|
||||
"prevSize": 12,
|
||||
"code": 921666,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 6,
|
||||
@@ -37,14 +53,14 @@
|
||||
"prevSize": 12,
|
||||
"code": 921865,
|
||||
"name": "icon12-folder",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"id": 0,
|
||||
"metadata": {
|
||||
"name": "openmct-symbols-12px",
|
||||
"name": "Open MCT Symbols 12px",
|
||||
"importSize": {
|
||||
"width": 279,
|
||||
"width": 384,
|
||||
"height": 384
|
||||
},
|
||||
"designer": "Charles Hacskaylo"
|
||||
@@ -52,6 +68,28 @@
|
||||
"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": [
|
||||
@@ -60,26 +98,11 @@
|
||||
"M597.333 768h-170.667v256h170.667v-256z",
|
||||
"M256 426.667h-256v170.667h256v-170.667z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"attrs": [],
|
||||
"grid": 0,
|
||||
"tags": [
|
||||
"icon12-crosshair"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"1161751": [
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
@@ -95,39 +118,12 @@
|
||||
"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,
|
||||
@@ -136,24 +132,11 @@
|
||||
"M0 426.667h1024v170.667h-1024v-170.667z",
|
||||
"M0 853.333h1024v170.667h-1024v-170.667z"
|
||||
],
|
||||
"attrs": [
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
],
|
||||
"isMulticolor": false,
|
||||
"isMulticolor2": false,
|
||||
"attrs": [],
|
||||
"grid": 0,
|
||||
"tags": [
|
||||
"icon12-list-view"
|
||||
],
|
||||
"colorPermutations": {
|
||||
"1161751": [
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
@@ -162,40 +145,14 @@
|
||||
"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": [
|
||||
[
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1
|
||||
],
|
||||
[
|
||||
0,
|
||||
161,
|
||||
75,
|
||||
1
|
||||
]
|
||||
]
|
||||
],
|
||||
"colorThemes": [],
|
||||
"colorThemeIdx": 0
|
||||
}
|
||||
],
|
||||
@@ -206,9 +163,9 @@
|
||||
"showQuickUse2": true,
|
||||
"showSVGs": true,
|
||||
"fontPref": {
|
||||
"prefix": "icon-",
|
||||
"prefix": "openmct-symbols-",
|
||||
"metadata": {
|
||||
"fontFamily": "openmct-symbols-12px",
|
||||
"fontFamily": "Open-MCT-Symbols-12px",
|
||||
"majorVersion": 1,
|
||||
"minorVersion": 0
|
||||
},
|
||||
@@ -217,7 +174,12 @@
|
||||
"baseline": 6.25,
|
||||
"whitespace": 50
|
||||
},
|
||||
"embed": false
|
||||
"embed": false,
|
||||
"noie8": true,
|
||||
"ie7": false,
|
||||
"showMetadata": false,
|
||||
"includeMetadata": false,
|
||||
"showMetrics": true
|
||||
},
|
||||
"imagePref": {
|
||||
"prefix": "icon-",
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"metadata": {
|
||||
"name": "Open MCT Symbols",
|
||||
"name": "Open MCT Symbols 16px",
|
||||
"lastOpened": 0,
|
||||
"created": 1541830438012
|
||||
"created": 1561482854927
|
||||
},
|
||||
"iconSets": [
|
||||
{
|
||||
@@ -317,13 +317,29 @@
|
||||
"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,
|
||||
@@ -331,7 +347,7 @@
|
||||
"name": "icon-arrows-up-down",
|
||||
"prevSize": 32,
|
||||
"code": 59905,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 68,
|
||||
@@ -339,7 +355,7 @@
|
||||
"name": "icon-bullet",
|
||||
"prevSize": 32,
|
||||
"code": 59906,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 150,
|
||||
@@ -347,7 +363,7 @@
|
||||
"prevSize": 32,
|
||||
"code": 59907,
|
||||
"name": "icon-calendar",
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 45,
|
||||
@@ -355,7 +371,7 @@
|
||||
"name": "icon-chain-links",
|
||||
"prevSize": 32,
|
||||
"code": 59908,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 73,
|
||||
@@ -363,7 +379,7 @@
|
||||
"name": "icon-download",
|
||||
"prevSize": 32,
|
||||
"code": 59909,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 39,
|
||||
@@ -371,7 +387,7 @@
|
||||
"name": "icon-duplicate",
|
||||
"prevSize": 32,
|
||||
"code": 59910,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 50,
|
||||
@@ -379,7 +395,7 @@
|
||||
"name": "icon-folder-new",
|
||||
"prevSize": 32,
|
||||
"code": 59911,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 138,
|
||||
@@ -387,7 +403,7 @@
|
||||
"name": "icon-fullscreen-collapse",
|
||||
"prevSize": 32,
|
||||
"code": 59912,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 139,
|
||||
@@ -395,7 +411,7 @@
|
||||
"name": "icon-fullscreen-expand",
|
||||
"prevSize": 32,
|
||||
"code": 59913,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 122,
|
||||
@@ -403,7 +419,7 @@
|
||||
"name": "icon-layers",
|
||||
"prevSize": 32,
|
||||
"code": 59914,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 151,
|
||||
@@ -411,7 +427,7 @@
|
||||
"name": "icon-line-horz",
|
||||
"prevSize": 32,
|
||||
"code": 59915,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 100,
|
||||
@@ -419,7 +435,7 @@
|
||||
"name": "icon-magnify",
|
||||
"prevSize": 32,
|
||||
"code": 59916,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 99,
|
||||
@@ -427,7 +443,7 @@
|
||||
"name": "icon-magnify-in",
|
||||
"prevSize": 32,
|
||||
"code": 59917,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 101,
|
||||
@@ -435,7 +451,7 @@
|
||||
"name": "icon-magnify-out-v2",
|
||||
"prevSize": 32,
|
||||
"code": 59918,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 103,
|
||||
@@ -443,7 +459,7 @@
|
||||
"name": "icon-menu",
|
||||
"prevSize": 32,
|
||||
"code": 59919,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 124,
|
||||
@@ -451,7 +467,7 @@
|
||||
"name": "icon-move",
|
||||
"prevSize": 32,
|
||||
"code": 59920,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 7,
|
||||
@@ -459,7 +475,7 @@
|
||||
"name": "icon-new-window",
|
||||
"prevSize": 32,
|
||||
"code": 59921,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 63,
|
||||
@@ -467,7 +483,7 @@
|
||||
"name": "icon-paint-bucket-v2",
|
||||
"prevSize": 32,
|
||||
"code": 59922,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 15,
|
||||
@@ -475,7 +491,7 @@
|
||||
"name": "icon-pencil",
|
||||
"prevSize": 32,
|
||||
"code": 59923,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 54,
|
||||
@@ -483,7 +499,7 @@
|
||||
"name": "icon-pencil-edit-in-place",
|
||||
"prevSize": 32,
|
||||
"code": 59924,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 40,
|
||||
@@ -491,7 +507,7 @@
|
||||
"name": "icon-play",
|
||||
"prevSize": 32,
|
||||
"code": 59925,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 125,
|
||||
@@ -499,7 +515,7 @@
|
||||
"name": "icon-pause",
|
||||
"prevSize": 32,
|
||||
"code": 59926,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 119,
|
||||
@@ -507,7 +523,7 @@
|
||||
"name": "icon-plot-resource",
|
||||
"prevSize": 32,
|
||||
"code": 59927,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 48,
|
||||
@@ -515,7 +531,7 @@
|
||||
"name": "icon-pointer-left",
|
||||
"prevSize": 32,
|
||||
"code": 59928,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 47,
|
||||
@@ -523,7 +539,7 @@
|
||||
"name": "icon-pointer-right",
|
||||
"prevSize": 32,
|
||||
"code": 59929,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 85,
|
||||
@@ -531,7 +547,7 @@
|
||||
"name": "icon-refresh",
|
||||
"prevSize": 32,
|
||||
"code": 59930,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 55,
|
||||
@@ -539,7 +555,7 @@
|
||||
"name": "icon-save",
|
||||
"prevSize": 32,
|
||||
"code": 59931,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 56,
|
||||
@@ -547,7 +563,7 @@
|
||||
"name": "icon-save-as",
|
||||
"prevSize": 32,
|
||||
"code": 59932,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 58,
|
||||
@@ -555,7 +571,7 @@
|
||||
"name": "icon-sine",
|
||||
"prevSize": 32,
|
||||
"code": 59933,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 113,
|
||||
@@ -563,7 +579,7 @@
|
||||
"name": "icon-font",
|
||||
"prevSize": 32,
|
||||
"code": 59934,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 41,
|
||||
@@ -571,7 +587,7 @@
|
||||
"name": "icon-thumbs-strip",
|
||||
"prevSize": 32,
|
||||
"code": 59935,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 146,
|
||||
@@ -579,7 +595,7 @@
|
||||
"name": "icon-two-parts-both",
|
||||
"prevSize": 32,
|
||||
"code": 59936,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 145,
|
||||
@@ -587,7 +603,7 @@
|
||||
"name": "icon-two-parts-one-only",
|
||||
"prevSize": 32,
|
||||
"code": 59937,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 82,
|
||||
@@ -595,7 +611,7 @@
|
||||
"name": "icon-resync",
|
||||
"prevSize": 32,
|
||||
"code": 59938,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 86,
|
||||
@@ -603,7 +619,7 @@
|
||||
"name": "icon-reset",
|
||||
"prevSize": 32,
|
||||
"code": 59939,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 61,
|
||||
@@ -611,7 +627,7 @@
|
||||
"name": "icon-x-in-circle",
|
||||
"prevSize": 32,
|
||||
"code": 59940,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 84,
|
||||
@@ -619,7 +635,7 @@
|
||||
"name": "icon-brightness",
|
||||
"prevSize": 32,
|
||||
"code": 59941,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 83,
|
||||
@@ -627,7 +643,7 @@
|
||||
"name": "icon-contrast",
|
||||
"prevSize": 32,
|
||||
"code": 59942,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 87,
|
||||
@@ -635,7 +651,7 @@
|
||||
"name": "icon-expand",
|
||||
"prevSize": 32,
|
||||
"code": 59943,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 89,
|
||||
@@ -643,7 +659,7 @@
|
||||
"name": "icon-list-view",
|
||||
"prevSize": 32,
|
||||
"code": 59944,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 133,
|
||||
@@ -651,7 +667,7 @@
|
||||
"name": "icon-grid-snap-to",
|
||||
"prevSize": 32,
|
||||
"code": 59945,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 132,
|
||||
@@ -659,7 +675,7 @@
|
||||
"name": "icon-grid-snap-no",
|
||||
"prevSize": 32,
|
||||
"code": 59946,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 94,
|
||||
@@ -667,7 +683,7 @@
|
||||
"name": "icon-frame-show",
|
||||
"prevSize": 32,
|
||||
"code": 59947,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 95,
|
||||
@@ -675,7 +691,7 @@
|
||||
"name": "icon-frame-hide",
|
||||
"prevSize": 32,
|
||||
"code": 59948,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 97,
|
||||
@@ -683,7 +699,7 @@
|
||||
"name": "icon-import",
|
||||
"prevSize": 32,
|
||||
"code": 59949,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 96,
|
||||
@@ -691,7 +707,7 @@
|
||||
"name": "icon-export",
|
||||
"prevSize": 32,
|
||||
"code": 59950,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 114,
|
||||
@@ -699,7 +715,7 @@
|
||||
"name": "icon-font-size",
|
||||
"prevSize": 32,
|
||||
"code": 59951,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 144,
|
||||
@@ -707,7 +723,7 @@
|
||||
"name": "icon-activity",
|
||||
"prevSize": 32,
|
||||
"code": 60160,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 104,
|
||||
@@ -715,7 +731,7 @@
|
||||
"name": "icon-activity-mode",
|
||||
"prevSize": 32,
|
||||
"code": 60161,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 137,
|
||||
@@ -723,7 +739,7 @@
|
||||
"name": "icon-autoflow-tabular",
|
||||
"prevSize": 32,
|
||||
"code": 60162,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 115,
|
||||
@@ -731,7 +747,7 @@
|
||||
"name": "icon-clock",
|
||||
"prevSize": 32,
|
||||
"code": 60163,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 2,
|
||||
@@ -739,7 +755,7 @@
|
||||
"name": "icon-database",
|
||||
"prevSize": 32,
|
||||
"code": 60164,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 3,
|
||||
@@ -747,7 +763,7 @@
|
||||
"name": "icon-database-query",
|
||||
"prevSize": 32,
|
||||
"code": 60165,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 67,
|
||||
@@ -755,7 +771,7 @@
|
||||
"name": "icon-dataset",
|
||||
"prevSize": 32,
|
||||
"code": 60166,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 59,
|
||||
@@ -763,7 +779,7 @@
|
||||
"name": "icon-datatable",
|
||||
"prevSize": 32,
|
||||
"code": 60167,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 136,
|
||||
@@ -771,7 +787,7 @@
|
||||
"name": "icon-dictionary",
|
||||
"prevSize": 32,
|
||||
"code": 60168,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 51,
|
||||
@@ -779,7 +795,7 @@
|
||||
"name": "icon-folder",
|
||||
"prevSize": 32,
|
||||
"code": 60169,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 147,
|
||||
@@ -787,7 +803,7 @@
|
||||
"name": "icon-image",
|
||||
"prevSize": 32,
|
||||
"code": 60170,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 4,
|
||||
@@ -795,7 +811,7 @@
|
||||
"name": "icon-layout",
|
||||
"prevSize": 32,
|
||||
"code": 60171,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 24,
|
||||
@@ -803,7 +819,7 @@
|
||||
"name": "icon-object",
|
||||
"prevSize": 32,
|
||||
"code": 60172,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 52,
|
||||
@@ -811,7 +827,7 @@
|
||||
"name": "icon-object-unknown",
|
||||
"prevSize": 32,
|
||||
"code": 60173,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 105,
|
||||
@@ -819,7 +835,7 @@
|
||||
"name": "icon-packet",
|
||||
"prevSize": 32,
|
||||
"code": 60174,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 126,
|
||||
@@ -827,7 +843,7 @@
|
||||
"name": "icon-page",
|
||||
"prevSize": 32,
|
||||
"code": 60175,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 130,
|
||||
@@ -835,7 +851,7 @@
|
||||
"name": "icon-plot-overlay",
|
||||
"prevSize": 32,
|
||||
"code": 60176,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 80,
|
||||
@@ -843,7 +859,7 @@
|
||||
"name": "icon-plot-stacked",
|
||||
"prevSize": 32,
|
||||
"code": 60177,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 134,
|
||||
@@ -851,7 +867,7 @@
|
||||
"name": "icon-session",
|
||||
"prevSize": 32,
|
||||
"code": 60178,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 109,
|
||||
@@ -859,7 +875,7 @@
|
||||
"name": "icon-tabular",
|
||||
"prevSize": 32,
|
||||
"code": 60179,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 107,
|
||||
@@ -867,7 +883,7 @@
|
||||
"name": "icon-tabular-lad",
|
||||
"prevSize": 32,
|
||||
"code": 60180,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 106,
|
||||
@@ -875,7 +891,7 @@
|
||||
"name": "icon-tabular-lad-set",
|
||||
"prevSize": 32,
|
||||
"code": 60181,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 70,
|
||||
@@ -883,7 +899,7 @@
|
||||
"name": "icon-tabular-realtime",
|
||||
"prevSize": 32,
|
||||
"code": 60182,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 60,
|
||||
@@ -891,7 +907,7 @@
|
||||
"name": "icon-tabular-scrolling",
|
||||
"prevSize": 32,
|
||||
"code": 60183,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 131,
|
||||
@@ -899,7 +915,7 @@
|
||||
"name": "icon-telemetry",
|
||||
"prevSize": 32,
|
||||
"code": 60184,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 108,
|
||||
@@ -907,7 +923,7 @@
|
||||
"name": "icon-timeline",
|
||||
"prevSize": 32,
|
||||
"code": 60185,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 81,
|
||||
@@ -915,7 +931,7 @@
|
||||
"name": "icon-timer",
|
||||
"prevSize": 32,
|
||||
"code": 60186,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 69,
|
||||
@@ -923,7 +939,7 @@
|
||||
"name": "icon-topic",
|
||||
"prevSize": 32,
|
||||
"code": 60187,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 79,
|
||||
@@ -931,7 +947,7 @@
|
||||
"name": "icon-box-with-dashed-lines-v2",
|
||||
"prevSize": 32,
|
||||
"code": 60188,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 90,
|
||||
@@ -939,7 +955,7 @@
|
||||
"name": "icon-summary-widget",
|
||||
"prevSize": 32,
|
||||
"code": 60189,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 92,
|
||||
@@ -947,7 +963,7 @@
|
||||
"name": "icon-notebook",
|
||||
"prevSize": 32,
|
||||
"code": 60190,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 118,
|
||||
@@ -955,7 +971,7 @@
|
||||
"name": "icon-tabs-view",
|
||||
"prevSize": 32,
|
||||
"code": 60191,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 117,
|
||||
@@ -963,7 +979,7 @@
|
||||
"name": "icon-flexible-layout",
|
||||
"prevSize": 32,
|
||||
"code": 60192,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 152,
|
||||
@@ -971,7 +987,7 @@
|
||||
"name": "icon-generator-sine",
|
||||
"prevSize": 32,
|
||||
"code": 60193,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 153,
|
||||
@@ -979,7 +995,7 @@
|
||||
"name": "icon-generator-event",
|
||||
"prevSize": 32,
|
||||
"code": 60194,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
},
|
||||
{
|
||||
"order": 160,
|
||||
@@ -987,7 +1003,7 @@
|
||||
"name": "icon-gauge",
|
||||
"prevSize": 32,
|
||||
"code": 60195,
|
||||
"tempChar": ""
|
||||
"tempChar": ""
|
||||
}
|
||||
],
|
||||
"id": 0,
|
||||
@@ -1602,6 +1618,46 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"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-12px.ttf
Normal file
BIN
src/styles-new/fonts/Open-MCT-Symbols-12px.ttf
Normal file
Binary file not shown.
BIN
src/styles-new/fonts/Open-MCT-Symbols-12px.woff
Normal file
BIN
src/styles-new/fonts/Open-MCT-Symbols-12px.woff
Normal file
Binary file not shown.
BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.ttf
Executable file → Normal file
BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.ttf
Executable file → Normal file
Binary file not shown.
BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.woff
Executable file → Normal file
BIN
src/styles-new/fonts/Open-MCT-Symbols-16px.woff
Executable file → Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -26,7 +26,7 @@
|
||||
@import "constants";
|
||||
@import "constants-mobile.scss";
|
||||
//@import "constants-espresso"; // TEMP
|
||||
@import "constants-snow"; // TEMP
|
||||
//@import "constants-maelstrom";
|
||||
//@import "constants-snow"; // TEMP
|
||||
@import "constants-maelstrom";
|
||||
@import "mixins";
|
||||
@import "animations";
|
||||
19
src/styles-new/theme-maelstrom.scss
Normal file
19
src/styles-new/theme-maelstrom.scss
Normal file
@@ -0,0 +1,19 @@
|
||||
/************* FRAMES */
|
||||
.c-so-view {
|
||||
&__header {
|
||||
transform: translateY(3px);
|
||||
}
|
||||
|
||||
&__header__name {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
&:not(.c-so-view--no-frame) {
|
||||
$bc: #666;
|
||||
$bLR: 3px solid transparent;
|
||||
$br: 20px;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,8 @@
|
||||
class="c-so-view__object-view"
|
||||
ref="objectView"
|
||||
:object="domainObject"
|
||||
:show-edit-view="showEditView">
|
||||
:show-edit-view="showEditView"
|
||||
:object-path="objectPath">
|
||||
</object-view>
|
||||
</div>
|
||||
</template>
|
||||
@@ -123,7 +124,12 @@
|
||||
.c-click-icon,
|
||||
.c-button {
|
||||
// Shrink buttons a bit when they appear in a frame
|
||||
font-size: 0.8em;
|
||||
align-items: baseline;
|
||||
font-size: 0.85em;
|
||||
padding: 3px 5px;
|
||||
&:before {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,7 +9,8 @@ export default {
|
||||
props: {
|
||||
view: String,
|
||||
object: Object,
|
||||
showEditView: Boolean
|
||||
showEditView: Boolean,
|
||||
objectPath: Array
|
||||
},
|
||||
destroyed() {
|
||||
this.clear();
|
||||
@@ -61,6 +62,8 @@ export default {
|
||||
if (this.composition) {
|
||||
this.composition._destroy();
|
||||
}
|
||||
|
||||
this.openmct.objectViews.off('clearData', this.clearData);
|
||||
},
|
||||
invokeEditModeHandler(editMode) {
|
||||
this.currentView.onEditModeChange(editMode);
|
||||
@@ -89,17 +92,19 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
let objectPath = this.currentObjectPath || this.objectPath;
|
||||
|
||||
if (provider.edit && this.showEditView) {
|
||||
if (this.openmct.editor.isEditing()) {
|
||||
this.currentView = provider.edit(this.currentObject);
|
||||
this.currentView = provider.edit(this.currentObject, true, objectPath);
|
||||
} else {
|
||||
this.currentView = provider.view(this.currentObject, false);
|
||||
this.currentView = provider.view(this.currentObject, false, objectPath);
|
||||
}
|
||||
|
||||
this.openmct.editor.on('isEditing', this.toggleEditView);
|
||||
this.releaseEditModeHandler = () => this.openmct.editor.off('isEditing', this.toggleEditView);
|
||||
} else {
|
||||
this.currentView = provider.view(this.currentObject, this.openmct.editor.isEditing());
|
||||
this.currentView = provider.view(this.currentObject, this.openmct.editor.isEditing(), objectPath);
|
||||
|
||||
if (this.currentView.onEditModeChange) {
|
||||
this.openmct.editor.on('isEditing', this.invokeEditModeHandler);
|
||||
@@ -112,8 +117,10 @@ export default {
|
||||
this.removeSelectable = openmct.selection.selectable(
|
||||
this.$el, this.getSelectionContext(), true);
|
||||
}
|
||||
|
||||
this.openmct.objectViews.on('clearData', this.clearData);
|
||||
},
|
||||
show(object, viewKey, immediatelySelect) {
|
||||
show(object, viewKey, immediatelySelect, currentObjectPath) {
|
||||
if (this.unlisten) {
|
||||
this.unlisten();
|
||||
}
|
||||
@@ -128,6 +135,11 @@ export default {
|
||||
}
|
||||
|
||||
this.currentObject = object;
|
||||
|
||||
if (currentObjectPath) {
|
||||
this.currentObjectPath = currentObjectPath;
|
||||
}
|
||||
|
||||
this.unlisten = this.openmct.objects.observe(this.currentObject, '*', (mutatedObject) => {
|
||||
this.currentObject = mutatedObject;
|
||||
});
|
||||
@@ -187,6 +199,22 @@ 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,6 @@ import _ from 'lodash';
|
||||
},
|
||||
methods: {
|
||||
updateSelection(selection) {
|
||||
if (_.isEqual(this.selection, selection)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.selection = selection;
|
||||
|
||||
if (this.selectedViews) {
|
||||
@@ -38,10 +34,6 @@ 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');
|
||||
|
||||
@@ -19,28 +19,11 @@
|
||||
</div>
|
||||
|
||||
<div class="l-browse-bar__end">
|
||||
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
v-if="views.length > 1">
|
||||
<button class="c-button--menu"
|
||||
:class="currentView.cssClass"
|
||||
title="Switch view type"
|
||||
@click.stop="toggleViewMenu">
|
||||
<span class="c-button__label">
|
||||
{{ currentView.name }}
|
||||
</span>
|
||||
</button>
|
||||
<div class="c-menu" v-show="showViewMenu">
|
||||
<ul>
|
||||
<li v-for="(view, index) in views"
|
||||
@click="setView(view)"
|
||||
:key="index"
|
||||
:class="view.cssClass"
|
||||
:title="view.name">
|
||||
{{ view.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<view-switcher
|
||||
:currentView="currentView"
|
||||
:views="views"
|
||||
@setView="setView">
|
||||
</view-switcher>
|
||||
<!-- Action buttons -->
|
||||
<div class="l-browse-bar__actions">
|
||||
<button v-if="notebookEnabled"
|
||||
@@ -77,14 +60,15 @@
|
||||
|
||||
<script>
|
||||
import NotebookSnapshot from '../utils/notebook-snapshot';
|
||||
import ViewSwitcher from './ViewSwitcher.vue';
|
||||
const PLACEHOLDER_OBJECT = {};
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
components: {
|
||||
ViewSwitcher
|
||||
},
|
||||
methods: {
|
||||
toggleViewMenu() {
|
||||
this.showViewMenu = !this.showViewMenu;
|
||||
},
|
||||
toggleSaveMenu() {
|
||||
this.showSaveMenu = !this.showSaveMenu;
|
||||
},
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
<div class="l-shell" :class="{
|
||||
'is-editing': isEditing
|
||||
}">
|
||||
<div class="l-shell__head">
|
||||
<div class="l-shell__head" :class="{
|
||||
'l-shell__head--expanded': headExpanded,
|
||||
'l-shell__head--minify-indicators': !headExpanded
|
||||
}">
|
||||
<CreateButton class="l-shell__create-button"></CreateButton>
|
||||
<div class="l-shell__controls">
|
||||
<indicators class="l-shell__head-section l-shell__indicators">
|
||||
</indicators>
|
||||
<notification-banner></notification-banner>
|
||||
<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"
|
||||
target="_blank">
|
||||
@@ -15,6 +21,8 @@
|
||||
</button>
|
||||
</div>
|
||||
<app-logo></app-logo>
|
||||
<button class="l-shell__head__collapse-button c-button"
|
||||
@click="toggleShellHead"></button>
|
||||
</div>
|
||||
<multipane class="l-shell__main"
|
||||
type="horizontal">
|
||||
@@ -44,9 +52,6 @@
|
||||
<Inspector :isEditing="isEditing" ref="inspector"></Inspector>
|
||||
</pane>
|
||||
</multipane>
|
||||
<div class="l-shell__status">
|
||||
<StatusBar></StatusBar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -61,12 +66,6 @@
|
||||
flex-flow: column nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
&__status {
|
||||
background: $colorStatusBarBg;
|
||||
color: $colorStatusBarFg;
|
||||
padding: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&__pane-tree {
|
||||
width: 40%;
|
||||
|
||||
@@ -160,14 +159,52 @@
|
||||
}
|
||||
|
||||
&__head {
|
||||
align-items: center;
|
||||
align-items: stretch;
|
||||
background: $colorHeadBg;
|
||||
justify-content: space-between;
|
||||
padding: $interiorMargin;
|
||||
padding: $interiorMargin $interiorMargin + 2;
|
||||
|
||||
> [class*="__"] + [class*="__"] {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
&-section {
|
||||
// Subdivides elements across the head
|
||||
display: flex;
|
||||
flex: 0 1 auto;
|
||||
padding: 0 $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,
|
||||
@@ -175,11 +212,17 @@
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
&__controls {
|
||||
flex: 1 1 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 2.5%;
|
||||
&__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;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************* MAIN AREA */
|
||||
@@ -266,9 +309,10 @@
|
||||
import multipane from './multipane.vue';
|
||||
import pane from './pane.vue';
|
||||
import BrowseBar from './BrowseBar.vue';
|
||||
import StatusBar from './status-bar/StatusBar.vue';
|
||||
import Toolbar from '../toolbar/Toolbar.vue';
|
||||
import AppLogo from './AppLogo.vue';
|
||||
import Indicators from './status-bar/Indicators.vue';
|
||||
import NotificationBanner from './status-bar/NotificationBanner.vue';
|
||||
|
||||
var enterFullScreen = () => {
|
||||
var docElm = document.documentElement;
|
||||
@@ -309,9 +353,10 @@
|
||||
multipane,
|
||||
pane,
|
||||
BrowseBar,
|
||||
StatusBar,
|
||||
Toolbar,
|
||||
AppLogo
|
||||
AppLogo,
|
||||
Indicators,
|
||||
NotificationBanner
|
||||
},
|
||||
mounted() {
|
||||
this.openmct.editor.on('isEditing', (isEditing)=>{
|
||||
@@ -321,11 +366,18 @@
|
||||
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
|
||||
hasToolbar: false,
|
||||
headExpanded
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -334,6 +386,18 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
toggleShellHead() {
|
||||
this.headExpanded = !this.headExpanded;
|
||||
|
||||
window.localStorage.setItem(
|
||||
'openmct-shell-head',
|
||||
JSON.stringify(
|
||||
{
|
||||
expanded: this.headExpanded
|
||||
}
|
||||
)
|
||||
);
|
||||
},
|
||||
fullScreenToggle() {
|
||||
if (this.fullScreen) {
|
||||
this.fullScreen = false;
|
||||
|
||||
55
src/ui/layout/ViewSwitcher.vue
Normal file
55
src/ui/layout/ViewSwitcher.vue
Normal file
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
v-if="views.length > 1">
|
||||
<button class="c-button--menu"
|
||||
:class="currentView.cssClass"
|
||||
title="Switch view type"
|
||||
@click.stop="toggleViewMenu">
|
||||
<span class="c-button__label">
|
||||
{{ currentView.name }}
|
||||
</span>
|
||||
</button>
|
||||
<div class="c-menu" v-show="showViewMenu">
|
||||
<ul>
|
||||
<li v-for="(view, index) in views"
|
||||
@click="setView(view)"
|
||||
:key="index"
|
||||
:class="view.cssClass"
|
||||
:title="view.name">
|
||||
{{ view.name }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: [
|
||||
'currentView',
|
||||
'views'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
showViewMenu: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setView(view) {
|
||||
this.$emit('setView', view);
|
||||
},
|
||||
toggleViewMenu() {
|
||||
this.showViewMenu = !this.showViewMenu;
|
||||
},
|
||||
hideViewMenu() {
|
||||
this.showViewMenu = false;
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener('click', this.hideViewMenu);
|
||||
},
|
||||
destroyed() {
|
||||
document.removeEventListener('click', this.hideViewMenu);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -148,21 +148,6 @@
|
||||
font-size: floor(12px * .9);
|
||||
}
|
||||
|
||||
&__collapse-button {
|
||||
box-shadow: none;
|
||||
background: $splitterBtnColorBg;
|
||||
color: $splitterBtnColorFg;
|
||||
border-radius: $smallCr;
|
||||
font-size: 6px;
|
||||
line-height: 90%;
|
||||
padding: 3px 15px;
|
||||
|
||||
@include hover() {
|
||||
background: $colorBtnBgHov;
|
||||
color: $colorBtnFgHov;
|
||||
}
|
||||
}
|
||||
|
||||
&__label {
|
||||
// Name of the pane
|
||||
@include ellipsize();
|
||||
|
||||
@@ -17,10 +17,137 @@
|
||||
at runtime from the About dialog for additional information.
|
||||
-->
|
||||
<template>
|
||||
<span id='status' class='status-holder'></span>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-indicator {
|
||||
@include cControl();
|
||||
@include cClickIconButtonLayout();
|
||||
button { text-transform: uppercase; }
|
||||
|
||||
background: none !important;
|
||||
border-radius: $controlCr;
|
||||
overflow: visible;
|
||||
position: relative;
|
||||
text-transform: uppercase;
|
||||
|
||||
|
||||
&.no-minify {
|
||||
// For items that cannot be minified
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
align-items: center;
|
||||
|
||||
> *,
|
||||
&:before {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
&:before {
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.no-minify) {
|
||||
&: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;
|
||||
left: 0;
|
||||
top: 130%;
|
||||
padding: $interiorMargin $interiorMargin;
|
||||
position: absolute;
|
||||
transform-origin: 10px 0;
|
||||
transform: scale(0.0);
|
||||
overflow: visible;
|
||||
z-index: 50;
|
||||
|
||||
&:before {
|
||||
// Infobubble-style arrow element
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
@include triangle('up', $size: 4px, $ratio: 1, $color: $colorIndicatorMenuBg);
|
||||
}
|
||||
}
|
||||
|
||||
.c-indicator__count {
|
||||
display: inline-block;
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
// Hide the clock indicator when we're phone portrait
|
||||
body.phone.portrait {
|
||||
.c-indicator.t-indicator-clock {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@@ -29,12 +156,7 @@
|
||||
|
||||
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
|
||||
var wrapperNode = document.createElement('span');
|
||||
wrapperNode.className = 'l-indicator';
|
||||
wrapperNode.appendChild(indicator.element);
|
||||
this.$el.appendChild(wrapperNode);
|
||||
this.$el.appendChild(indicator.element);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,20 +57,19 @@
|
||||
|
||||
.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%;
|
||||
padding: $interiorMargin $interiorMargin $interiorMargin $interiorMarginLg;
|
||||
max-height: 25px;
|
||||
padding: $interiorMarginSm $interiorMargin $interiorMarginSm $interiorMarginLg;
|
||||
position: absolute;
|
||||
transform: translateX(-50%);
|
||||
bottom: $m;
|
||||
transform: translate(-50%, -50%);
|
||||
z-index: 2;
|
||||
|
||||
> * + * {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user