Skip to content

Commit 12e6939

Browse files
authored
Merge pull request nasa#1500 from nasa/open1469
[Features] Added Autoflow Tabular to open source features. Fixes nasa#1469
2 parents 3ce954c + 59c61e7 commit 12e6939

File tree

9 files changed

+1206
-2
lines changed

9 files changed

+1206
-2
lines changed

platform/features/autoflow/plugin.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
define([
2+
'text!./res/templates/autoflow-tabular.html',
3+
'./src/AutoflowTabularController',
4+
'./src/MCTAutoflowTable'
5+
], function (
6+
autoflowTabularTemplate,
7+
AutoflowTabularController,
8+
MCTAutoflowTable
9+
) {
10+
return function (options) {
11+
return function (openmct) {
12+
openmct.legacyRegistry.register("platform/features/autoflow", {
13+
"name": "WARP Telemetry Adapter",
14+
"description": "Retrieves telemetry from the WARP Server and provides related types and views.",
15+
"resources": "res",
16+
"extensions": {
17+
"views": [
18+
{
19+
"key": "autoflow",
20+
"name": "Autoflow Tabular",
21+
"cssClass": "icon-packet",
22+
"description": "A tabular view of packet contents.",
23+
"template": autoflowTabularTemplate,
24+
"type": options && options.type,
25+
"needs": [
26+
"telemetry"
27+
],
28+
"delegation": true
29+
}
30+
],
31+
"controllers": [
32+
{
33+
"key": "AutoflowTabularController",
34+
"implementation": AutoflowTabularController,
35+
"depends": [
36+
"$scope",
37+
"$timeout",
38+
"telemetrySubscriber"
39+
]
40+
}
41+
],
42+
"directives": [
43+
{
44+
"key": "mctAutoflowTable",
45+
"implementation": MCTAutoflowTable
46+
}
47+
]
48+
}
49+
});
50+
openmct.legacyRegistry.enable("platform/features/autoflow");
51+
};
52+
};
53+
});
54+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<div class="items-holder abs contents autoflow obj-value-format"
2+
ng-controller="AutoflowTabularController as autoflow">
3+
<div class="abs l-flex-row holder t-autoflow-header l-autoflow-header">
4+
<mct-include key="'input-filter'"
5+
ng-model="autoflow.filter"
6+
class="flex-elem">
7+
</mct-include>
8+
<div class="flex-elem grows t-last-update" title="Last Update">{{autoflow.updated()}}</div>
9+
<a title="Change column width"
10+
class="s-button flex-elem icon-arrows-right-left change-column-width"
11+
ng-click="autoflow.increaseColumnWidth()"></a>
12+
</div>
13+
<div class="abs t-autoflow-items l-autoflow-items"
14+
mct-resize="autoflow.setBounds(bounds)"
15+
mct-resize-interval="50">
16+
<mct-autoflow-table values="autoflow.rangeValues()"
17+
objects="autoflow.getTelemetryObjects()"
18+
rows="autoflow.getRows()"
19+
classes="autoflow.classes()"
20+
updated="autoflow.updated()"
21+
column-width="autoflow.columnWidth()"
22+
counter="autoflow.counter()"
23+
>
24+
</mct-autoflow-table>
25+
</div>
26+
</div>
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*global angular*/
2+
define(
3+
[],
4+
function () {
5+
6+
/**
7+
* The link step for the `mct-autoflow-table` directive;
8+
* watches scope and updates the DOM appropriately.
9+
* See documentation in `MCTAutoflowTable.js` for the rationale
10+
* for including this directive, as well as for an explanation
11+
* of which values are placed in scope.
12+
*
13+
* @constructor
14+
* @param {Scope} scope the scope for this usage of the directive
15+
* @param element the jqLite-wrapped element which used this directive
16+
*/
17+
function AutoflowTableLinker(scope, element) {
18+
var objects, // Domain objects at last structure refresh
19+
rows, // Number of rows from last structure refresh
20+
priorClasses = {},
21+
valueSpans = {}; // Span elements to put data values in
22+
23+
// Create a new name-value pair in the specified column
24+
function createListItem(domainObject, ul) {
25+
// Create a new li, and spans to go in it.
26+
var li = angular.element('<li>'),
27+
titleSpan = angular.element('<span>'),
28+
valueSpan = angular.element('<span>');
29+
30+
// Place spans in the li, and li into the column.
31+
// valueSpan must precede titleSpan in the DOM due to new CSS float approach
32+
li.append(valueSpan).append(titleSpan);
33+
ul.append(li);
34+
35+
// Style appropriately
36+
li.addClass('l-autoflow-row');
37+
titleSpan.addClass('l-autoflow-item l');
38+
valueSpan.addClass('l-autoflow-item r l-obj-val-format');
39+
40+
// Set text/tooltip for the name-value row
41+
titleSpan.text(domainObject.getModel().name);
42+
titleSpan.attr("title", domainObject.getModel().name);
43+
44+
// Keep a reference to the span which will hold the
45+
// data value, to populate in the next refreshValues call
46+
valueSpans[domainObject.getId()] = valueSpan;
47+
48+
return li;
49+
}
50+
51+
// Create a new column of name-value pairs in this table.
52+
function createColumn(el) {
53+
// Create a ul
54+
var ul = angular.element('<ul>');
55+
56+
// Add it into the mct-autoflow-table
57+
el.append(ul);
58+
59+
// Style appropriately
60+
ul.addClass('l-autoflow-col');
61+
62+
// Get the current col width and apply at time of column creation
63+
// Important to do this here, as new columns could be created after
64+
// the user has changed the width.
65+
ul.css('width', scope.columnWidth + 'px');
66+
67+
// Return it, so some li elements can be added
68+
return ul;
69+
}
70+
71+
// Change the width of the columns when user clicks the resize button.
72+
function resizeColumn() {
73+
element.find('ul').css('width', scope.columnWidth + 'px');
74+
}
75+
76+
// Rebuild the DOM associated with this table.
77+
function rebuild(domainObjects, rowCount) {
78+
var activeColumn;
79+
80+
// Empty out our cached span elements
81+
valueSpans = {};
82+
83+
// Start with an empty DOM beneath this directive
84+
element.html("");
85+
86+
// Add DOM elements for each domain object being displayed
87+
// in this table.
88+
domainObjects.forEach(function (object, index) {
89+
// Start a new column if we'd run out of room
90+
if (index % rowCount === 0) {
91+
activeColumn = createColumn(element);
92+
}
93+
// Add the DOM elements for that object to whichever
94+
// column (a `ul` element) is current.
95+
createListItem(object, activeColumn);
96+
});
97+
}
98+
99+
// Update spans with values, as made available via the
100+
// `values` attribute of this directive.
101+
function refreshValues() {
102+
// Get the available values
103+
var values = scope.values || {},
104+
classes = scope.classes || {};
105+
106+
// Populate all spans with those values (or clear
107+
// those spans if no value is available)
108+
(objects || []).forEach(function (object) {
109+
var id = object.getId(),
110+
span = valueSpans[id],
111+
value;
112+
113+
if (span) {
114+
// Look up the value...
115+
value = values[id];
116+
// ...and convert to empty string if it's undefined
117+
value = value === undefined ? "" : value;
118+
span.attr("data-value", value);
119+
120+
// Update the span
121+
span.text(value);
122+
span.attr("title", value);
123+
span.removeClass(priorClasses[id]);
124+
span.addClass(classes[id]);
125+
priorClasses[id] = classes[id];
126+
}
127+
// Also need stale/alert/ok class
128+
// on span
129+
});
130+
}
131+
132+
// Refresh the DOM for this table, if necessary
133+
function refreshStructure() {
134+
// Only rebuild if number of rows or set of objects
135+
// has changed; otherwise, our structure is still valid.
136+
if (scope.objects !== objects ||
137+
scope.rows !== rows) {
138+
139+
// Track those values to support future refresh checks
140+
objects = scope.objects;
141+
rows = scope.rows;
142+
143+
// Rebuild the DOM
144+
rebuild(objects || [], rows || 1);
145+
146+
// Refresh all data values shown
147+
refreshValues();
148+
}
149+
}
150+
151+
// Changing the domain objects in use or the number
152+
// of rows should trigger a structure change (DOM rebuild)
153+
scope.$watch("objects", refreshStructure);
154+
scope.$watch("rows", refreshStructure);
155+
156+
// When the current column width has been changed, resize the column
157+
scope.$watch('columnWidth', resizeColumn);
158+
159+
// When the last-updated time ticks,
160+
scope.$watch("updated", refreshValues);
161+
162+
// Update displayed values when the counter changes.
163+
scope.$watch("counter", refreshValues);
164+
165+
}
166+
167+
return AutoflowTableLinker;
168+
}
169+
);

0 commit comments

Comments
 (0)