Compare commits

..

2 Commits

Author SHA1 Message Date
Deep Tailor
1dbcdb618b add dynamic bars according to numnber of telemetry sources 2018-06-19 14:32:18 -07:00
Deep Tailor
dabe4e700c register BarGraph plugin plus working view 2018-06-12 13:44:05 -07:00
529 changed files with 7756 additions and 12778 deletions

88
API.md
View File

@@ -37,7 +37,7 @@
- [Time Systems and Bounds](#time-systems-and-bounds) - [Time Systems and Bounds](#time-systems-and-bounds)
- [Defining and Registering Time Systems](#defining-and-registering-time-systems) - [Defining and Registering Time Systems](#defining-and-registering-time-systems)
- [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system) - [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system)
- [Time Bounds](#time-bounds) - [Time Bounds](#time-bounds)
- [Clocks](#clocks) - [Clocks](#clocks)
- [Defining and registering clocks](#defining-and-registering-clocks) - [Defining and registering clocks](#defining-and-registering-clocks)
- [Getting and setting active clock](#getting-and-setting-active-clock) - [Getting and setting active clock](#getting-and-setting-active-clock)
@@ -48,10 +48,6 @@
- [The Time Conductor](#the-time-conductor) - [The Time Conductor](#the-time-conductor)
- [Time Conductor Configuration](#time-conductor-configuration) - [Time Conductor Configuration](#time-conductor-configuration)
- [Example conductor configuration](#example-conductor-configuration) - [Example conductor configuration](#example-conductor-configuration)
- [Indicators](#indicators)
- [The URL Status Indicator](#the-url-status-indicator)
- [Creating a Simple Indicator](#creating-a-simple-indicator)
- [Custom Indicators](#custom-indicators)
- [Included Plugins](#included-plugins) - [Included Plugins](#included-plugins)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -692,7 +688,7 @@ openmct.time.timeSystem(utcTimeSystem, bounds);
Setting the active time system will trigger a [`'timeSystem'`](#time-events) Setting the active time system will trigger a [`'timeSystem'`](#time-events)
event. If you supplied bounds, a [`'bounds'`](#time-events) event will be triggered afterwards with your newly supplied bounds. event. If you supplied bounds, a [`'bounds'`](#time-events) event will be triggered afterwards with your newly supplied bounds.
#### Time Bounds ### Time Bounds
The TimeAPI provides a getter/setter for querying and setting time bounds. Time The TimeAPI provides a getter/setter for querying and setting time bounds. Time
bounds are simply an object with a `start` and an end `end` attribute. bounds are simply an object with a `start` and an end `end` attribute.
@@ -981,72 +977,6 @@ openmct.install(openmct.plugins.Conductor({
})); }));
``` ```
## Indicators
Indicators are small widgets that reside at the bottom of the screen and are visible from
every screen in Open MCT. They can be used to convey system state using an icon and text.
Typically an indicator will display an icon (customizable with a CSS class) that will
reveal additional information when the mouse cursor is hovered over it.
### The URL Status Indicator
A common use case for indicators is to convey the state of some external system such as a
persistence backend or HTTP server. So long as this system is accessible via HTTP request,
Open MCT provides a general purpose indicator to show whether the server is available and
returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See
[Included Plugins](#included-plugins) below for details on how to install and configure the
URL Status Indicator.
### Creating a Simple Indicator
A simple indicator with an icon and some text can be created and added with minimal code. An indicator
of this type exposes functions for customizing the text, icon, and style of the indicator.
eg.
``` javascript
var myIndicator = openmct.indicators.simpleIndicator();
myIndicator.text("Hello World!");
openmct.indicators.add(myIndicator);
```
This will create a new indicator and add it to the bottom of the screen in Open MCT.
By default, the indicator will appear as an information icon. Hovering over the icon will
reveal the text set via the call to `.text()`. The Indicator object returned by the API
call exposes a number of functions for customizing the content and appearance of the indicator:
* `.text([text])`: Gets or sets the text shown when the user hovers over the indicator.
Accepts an __optional__ `string` argument that, if provided, will be used to set the text.
Hovering over the indicator will expand it to its full size, revealing this text alongside
the icon. Returns the currently set text as a `string`.
* `.description([description])`: Gets or sets the indicator's description. Accepts an
__optional__ `string` argument that, if provided, will be used to set the text. The description
allows for more detail to be provided in a tooltip when the user hovers over the indicator.
Returns the currently set text as a `string`.
* `.iconClass([className])`: Gets or sets the CSS class used to define the icon. Accepts an __optional__
`string` parameter to be used to set the class applied to the indicator. Any of
[the built-in glyphs](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs)
may be used here, or a custom CSS class can be provided. Returns the currently defined CSS
class as a `string`.
* `.statusClass([className])`: Gets or sets the CSS class used to determine status. Accepts an __optional __
`string` parameter to be used to set a status class applied to the indicator. May be used to apply
different colors to indicate status.
### Custom Indicators
A completely custom indicator can be added by simple providing a DOM element to place alongside other indicators.
``` javascript
var domNode = document.createElement('div');
domNode.innerText = new Date().toString();
setInterval(function () {
domNode.innerText = new Date().toString();
}, 1000);
openmct.indicators.add({
element: domNode
});
```
## Included Plugins ## Included Plugins
Open MCT is packaged along with a few general-purpose plugins: Open MCT is packaged along with a few general-purpose plugins:
@@ -1070,18 +1000,18 @@ openmct.install(openmct.plugins.CouchDB('http://localhost:9200'))
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different * `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
themes (dark and light) available for Open MCT. Note that at least one themes (dark and light) available for Open MCT. Note that at least one
of these themes must be installed for Open MCT to appear correctly. of these themes must be installed for Open MCT to appear correctly.
* `openmct.plugins.URLIndicator` adds an indicator which shows the * `openmct.plugins.URLIndicatorPlugin` adds an indicator which shows the
availability of a URL with the following options: availability of a URL with the following options:
- `url` : URL to indicate the status of - `url` : URL to indicate the status of
- `iconClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items) - `cssClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
- `interval`: Interval between checking the connection, defaults to `10000` - `interval`: Interval between checking the connection, defaults to `10000`
- `label` Name showing up as text in the status bar, defaults to url - `label` Name showing up as text in the status bar, defaults to url
```javascript ```javascript
openmct.install(openmct.plugins.URLIndicator({ openmct.install(openmct.plugins.URLIndicatorPlugin({
url: 'http://localhost:8080', url: 'http://google.com',
iconClass: 'check', cssClass: 'check',
interval: 10000, interval: 10000,
label: 'Localhost' label: 'Google'
}) })
); );
``` ```

5
app.js
View File

@@ -19,7 +19,6 @@
// Defaults // Defaults
options.port = options.port || options.p || 8080; options.port = options.port || options.p || 8080;
options.host = options.host || options.h || 'localhost'
options.directory = options.directory || options.D || '.'; options.directory = options.directory || options.D || '.';
['include', 'exclude', 'i', 'x'].forEach(function (opt) { ['include', 'exclude', 'i', 'x'].forEach(function (opt) {
options[opt] = options[opt] || []; options[opt] = options[opt] || [];
@@ -79,7 +78,7 @@
app.use(express['static'](options.directory)); app.use(express['static'](options.directory));
// Finally, open the HTTP server and log the instance to the console // Finally, open the HTTP server and log the instance to the console
app.listen(options.port, options.host, function() { app.listen(options.port, function() {
console.log('Open MCT application running at %s:%s', options.host, options.port) console.log('Open MCT application running at localhost:' + options.port)
}); });
}()); }());

View File

@@ -22,6 +22,7 @@
"eventemitter3": "^1.2.0", "eventemitter3": "^1.2.0",
"lodash": "3.10.1", "lodash": "3.10.1",
"almond": "~0.3.2", "almond": "~0.3.2",
"html2canvas": "^0.4.1",
"moment-timezone": "^0.5.13" "moment-timezone": "^0.5.13"
} }
} }

View File

@@ -60,8 +60,8 @@ define([
"source": "eventGenerator", "source": "eventGenerator",
"domains": [ "domains": [
{ {
"key": "utc", "key": "time",
"name": "Timestamp", "name": "Time",
"format": "utc" "format": "utc"
} }
], ],

View File

@@ -30,7 +30,6 @@ define([
{ {
key: "sin", key: "sin",
name: "Sine", name: "Sine",
formatString: '%0.2f',
hints: { hints: {
range: 1 range: 1
} }
@@ -38,7 +37,6 @@ define([
{ {
key: "cos", key: "cos",
name: "Cosine", name: "Cosine",
formatString: '%0.2f',
hints: { hints: {
range: 2 range: 2
} }

View File

@@ -72,7 +72,7 @@ define([
var data = []; var data = [];
while (start <= end && data.length < 5000) { while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, duration, domainObject.name)); data.push(pointForTimestamp(start, duration, domainObject.name));
start += duration; start += 5000;
} }
return Promise.resolve(data); return Promise.resolve(data);
}; };

View File

@@ -38,8 +38,7 @@ define([
"provides": "identityService", "provides": "identityService",
"type": "provider", "type": "provider",
"depends": [ "depends": [
"dialogService", "dialogService"
"$q"
] ]
} }
] ]

View File

@@ -55,37 +55,21 @@ define(
* @implements {IdentityService} * @implements {IdentityService}
* @memberof platform/identity * @memberof platform/identity
*/ */
function ExampleIdentityProvider(dialogService, $q) { function ExampleIdentityProvider(dialogService) {
this.dialogService = dialogService; // Handle rejected dialog messages by treating the
this.$q = $q; // current user as undefined.
function echo(v) { return v; }
function giveUndefined() { return undefined; }
this.returnUser = this.returnUser.bind(this); this.userPromise =
this.returnUndefined = this.returnUndefined.bind(this); dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
.then(echo, giveUndefined);
} }
ExampleIdentityProvider.prototype.getUser = function () { ExampleIdentityProvider.prototype.getUser = function () {
if (this.user) { return this.userPromise;
return this.$q.when(this.user);
} else {
return this.dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
.then(this.returnUser, this.returnUndefined);
}
}; };
/**
* @private
*/
ExampleIdentityProvider.prototype.returnUser = function (user) {
return this.user = user;
}
/**
* @private
*/
ExampleIdentityProvider.prototype.returnUndefined = function () {
return undefined;
}
return ExampleIdentityProvider; return ExampleIdentityProvider;
} }
); );

View File

@@ -1,9 +1,9 @@
<span class="h-indicator" ng-controller="DialogLaunchController"> <span class="status block" ng-controller="DialogLaunchController">
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! --> <!-- 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"> <span class="status-indicator icon-box-with-arrow"></span><span class="label">
<a ng-click="launchProgress(true)">Known</a> <a ng-click="launchProgress(true)">Known</a> |
<a ng-click="launchProgress(false)">Unknown</a> <a ng-click="launchProgress(false)">Unknown</a> |
<a ng-click="launchError()">Error</a> <a ng-click="launchError()">Error</a> |
<a ng-click="launchInfo()">Info</a> <a ng-click="launchInfo()">Info</a>
</span></div> </span><span class="count"></span>
</span> </span>

View File

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

View File

@@ -58,10 +58,7 @@
position: relative; position: relative;
} }
.w-mct-example { .w-mct-example > div { margin-bottom: $interiorMarginLg; }
color: #ccc;
> div { margin-bottom: $interiorMarginLg; }
}
code, code,
pre { pre {

View File

@@ -149,21 +149,12 @@
<h2>Local Controls</h2> <h2>Local Controls</h2>
<div class="cols cols1-1"> <div class="cols cols1-1">
<div class="col"> <div class="col">
<p>Local controls are typically buttons and selects that provide actions in close proximity to a component.</p> <p>Local controls are typically buttons and selects that provide local control to an individual element. Typically, these controls are hidden in order to not block data display until the user hovers their cursor over an element, when the controls are displayed using a transition fade. Mousing out of the element fades the controls from view.</p>
<p>These controls can optionally be hidden to reduce clutter until the user hovers their cursor over an enclosing element. To use this approach, apply the class <code>.has-local-controls</code> to the element that should be aware of the hover and ensure that element encloses <code>.h-local-controls</code>.</p>
</div> </div>
<mct-example><div class="plot-display-area" style="padding: 10px; position: relative;"> <mct-example><div class="plot-display-area" style="height: 100px; padding: 10px; position: relative;">Hover over me
Some content in here <div class="l-local-controls gl-plot-local-controls t-plot-display-controls">
<div class="h-local-controls h-local-controls-overlay-content l-btn-set">
<a class="s-button icon-arrow-left" title="Restore previous pan/zoom"></a> <a class="s-button icon-arrow-left" title="Restore previous pan/zoom"></a>
<a class="s-button icon-reset" title="Reset pan/zoom"></a> <a class="s-button icon-arrows-out" title="Reset pan/zoom"></a>
</div>
</div>
<div class="plot-display-area has-local-controls" style="padding: 10px; position: relative;">
Hover here
<div class="h-local-controls h-local-controls-overlay-content local-controls-hidden l-btn-set">
<a class="s-button icon-arrow-left" title="Restore previous pan/zoom"></a>
<a class="s-button icon-reset" title="Reset pan/zoom"></a>
</div> </div>
</div></mct-example> </div></mct-example>
</div> </div>

View File

@@ -20,12 +20,12 @@
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<style> <style>
.w-mct-example div[class*="s-status"],
.w-mct-example span[class*="s-status"],
.w-mct-example div[class*="s-limit"], .w-mct-example div[class*="s-limit"],
.w-mct-example div[class*="s-status"],
.w-mct-example div[class*="s-unsynced"],
.w-mct-example span[class*="s-limit"] { .w-mct-example span[class*="s-limit"] {
border-radius: 3px; border-radius: 4px;
padding: 2px 5px; padding: 3px 7px;
} }
.w-mct-example table { .w-mct-example table {
width: 100%; width: 100%;
@@ -36,12 +36,65 @@
<h1>Status Indication</h1> <h1>Status Indication</h1>
<div class="l-section"> <div class="l-section">
<h2>Status Classes</h2> <h2>Overview</h2>
<p>Many elements in Open MCT need to articulate a dynamic status; Open MCT provides the following styles and conventions to handle this:</p>
<ul>
<li><strong>Limits</strong>: when telemetry values exceed minimum or maximum values, they can be violating limits. Limit styles include both color and iconography; color is used to indicate severity while icons are used to indicate direction, upper or lower.</li>
<li><strong>Status</strong>: Open MCT also provides a number or built-in Status styles allowing telemetry or other displayed information to be visually classified by type. Common uses for these classes are to visually denote event records.</li>
<li><strong>Synchronization</strong>: When the system is displaying real-time data, it is very important that displays clearly indicate when they are not doing so, such as when a plot if frozen while panning or zooming. Open MCT provides a style for this.</li>
</ul>
</div>
<div class="l-section">
<h2>Limits</h2>
<div class="cols cols1-1"> <div class="cols cols1-1">
<div class="col"> <div class="col">
<p>Status classes allow any block or inline-block element to be decorated in order to articulate a <p>Limit CSS classes can be applied to any block or inline element. Open MCT limit classes set color and optionally an icon, but don't effect other properties. Yellow and red limit classes can be used as is, or allow the application of any custom icon available in Open MCT's glyphs library. &quot;Level&quot; limit classes - upper and lower - always use an icon in addition to a color; Open MCT doesn't support level limits without color.</p>
status. Provided classes include color-only and color plus icon; custom icons can easily be <ul>
employed by using a color-only status class in combination with an <a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">glyph</a>.</p> <li>Color only</li>
<ul>
<li><code>s-limit-yellow</code>: A yellow limit.</li>
<li><code>s-limit-red</code>: A red limit.</li>
</ul>
<li>Color and icon</li>
<ul>
<li><code>s-limit-yellow-icon</code>: A yellow limit with icon.</li>
<li><code>s-limit-red-icon</code>: A red limit with icon.</li>
</ul>
<li>Upper and lower limit indicators. Must be used with a color limit class to be visible.</li>
<ul>
<li><code>s-limit-upr</code>: Upper limit.
</li>
<li><code>s-limit-lwr</code>: Lower limit.
</li>
</ul>
</ul>
</div>
<mct-example><div class="s-limit-yellow">Yellow limit</div>
<div class="s-limit-red">Red limit</div>
<div class="s-limit-yellow-icon">Yellow limit with icon</div>
<div class="s-limit-red-icon">Red limit with icon</div>
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
<div class="s-limit-red s-limit-upr">Upper red limit</div>
<div class="s-limit-red icon-bell">Red Limit with a custom icon</div>
<div>Some text with an <span class="s-limit-yellow-icon">inline element</span> showing a yellow limit.</div>
<!-- Limits applied in a table -->
<table>
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-bell">0.451</td><td>1.007</td></tr>
</table>
</mct-example>
</div>
</div>
<div class="l-section">
<h2>Status</h2>
<div class="cols cols1-1">
<div class="col">
<p>Classes here can be applied to elements as needed.</p>
<ul> <ul>
<li>Color only</li> <li>Color only</li>
<ul> <ul>
@@ -53,174 +106,36 @@
</ul> </ul>
<li>Color and icon</li> <li>Color and icon</li>
<ul> <ul>
<li><code>s-status-icon-warning-hi</code></li> <li><code>s-status-warning-hi-icon</code></li>
<li><code>s-status-icon-warning-lo</code></li> <li><code>s-status-warning-lo-icon</code></li>
<li><code>s-status-icon-diagnostic</code></li> <li><code>s-status-diagnostic-icon</code></li>
<li><code>s-status-icon-info</code></li> <li><code>s-status-info-icon</code></li>
<li><code>s-status-icon-ok</code></li> <li><code>s-status-ok-icon</code></li>
</ul> </ul>
</ul> </ul>
</div> </div>
<mct-example><!-- Color alone examples --> <mct-example><div class="s-status-warning-hi">WARNING HI</div>
<div class="s-status-warning-hi">WARNING HI</div>
<div class="s-status-warning-lo">WARNING LOW</div> <div class="s-status-warning-lo">WARNING LOW</div>
<div class="s-status-diagnostic">DIAGNOSTIC</div> <div class="s-status-diagnostic">DIAGNOSTIC</div>
<div class="s-status-info">INFO</div> <div class="s-status-info">INFO</div>
<div class="s-status-ok">OK</div> <div class="s-status-ok">OK</div>
<div class="s-status-warning-hi-icon">WARNING HI with icon</div>
<!-- Color and icon examples --> <div class="s-status-warning-lo-icon">WARNING LOW with icon</div>
<div class="s-status-icon-warning-hi">WARNING HI with icon</div> <div class="s-status-diagnostic-icon">DIAGNOSTIC with icon</div>
<div class="s-status-icon-warning-lo">WARNING LOW with icon</div> <div class="s-status-info-icon">INFO with icon</div>
<div class="s-status-icon-diagnostic">DIAGNOSTIC with icon</div> <div class="s-status-ok-icon">OK with icon</div>
<div class="s-status-icon-info">INFO with icon</div> <div class="s-status-warning-hi icon-gear">WARNING HI with custom icon</div>
<div class="s-status-icon-ok">OK with icon</div>
<div class="s-status-warning-hi icon-alert-triangle">WARNING HI with custom icon</div>
<div>Some text with an <span class="s-status-icon-diagnostic">inline element</span> showing a Diagnostic status.</div>
</mct-example> </mct-example>
</div> </div>
</div> </div>
<div class="l-section"> <div class="l-section">
<h2>Limit Classes</h2> <h2>Synchronization</h2>
<div class="cols cols1-1"> <div class="cols cols1-1">
<div class="col"> <div class="col">
<p>Limit classes are a specialized form of status, specifically meant to be applied to telemetry <p>When the system is operating in real-time streaming mode, it is important for views that display real-time data to clearly articulate when they are not, such as when a user zooms or pans a plot view, freezing that view. In that case, the CSS class <code>s-unsynced</code> should be applied to that view.</p>
displays to indicate that a limit threshold has been violated. Open MCT provides both severity
and direction classes; severity (yellow and red) can be used alone or in combination
with direction (upper or lower). Direction classes cannot be used on their own.</p>
<p>Like Status classes, Limits can be used as color-only, or color plus icon. Custom icons can
be applied in the same fashion as described above.</p>
<ul>
<li>Severity color alone</li>
<ul>
<li><code>s-limit-yellow</code>: A yellow limit.</li>
<li><code>s-limit-red</code>: A red limit.</li>
</ul>
<li>Severity color and icon</li>
<ul>
<li><code>s-limit-icon-yellow</code>: A yellow limit with icon.</li>
<li><code>s-limit-icon-red</code>: A red limit with icon.</li>
</ul>
<li>Direction indicators. MUST be used with a &quot;color alone&quot; limit class. See
examples for more.</li>
<ul>
<li><code>s-limit-upr</code>: Upper limit.</li>
<li><code>s-limit-lwr</code>: Lower limit.</li>
</ul>
</ul>
</div> </div>
<mct-example><!-- Color alone examples --> <mct-example><div class="s-unsynced">This element is unsynced</div>
<div class="s-limit-yellow">Yellow limit</div>
<div class="s-limit-red">Red limit</div>
<!-- Color and icon examples -->
<div class="s-limit-icon-yellow">Yellow limit with icon</div>
<div class="s-limit-icon-red">Red limit with icon</div>
<div class="s-limit-red icon-alert-rect">Red Limit with a custom icon</div>
<div>Some text with an <span class="s-limit-icon-yellow">inline element</span> showing a yellow limit.</div>
<!-- Severity and direction examples -->
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
<div class="s-limit-red s-limit-upr">Upper red limit</div>
<!-- Limits applied in a table -->
<table>
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-alert-triangle">0.451</td><td>1.007</td></tr>
</table>
</mct-example>
</div>
</div>
<div class="l-section">
<h2>Status Bar Indicators</h2>
<div class="cols cols1-1">
<div class="col">
<p>Indicators are small iconic notification elements that appear in the Status Bar area of
the application at the window's bottom. Indicators should be used to articulate the state of a
system and optionally provide gestures related to that system. They use a combination of icon and
color to identify themselves and articulate a state respectively.</p>
<h3>Recommendations</h3>
<ul>
<li><strong>Keep the icon consistent</strong>. The icon is the principal identifier of the system and is a valuable
recall aid for the user. Don't change the icon as a system's state changes, use color and
text for that purpose.</li>
<li><strong>Don't use the same icon more than once</strong>. Select meaningful and distinct icons so the user
will be able to quickly identify what they're looking for.</li>
</ul>
<h3>States</h3>
<ul>
<li><strong>Disabled</strong>: The system is not available to the user.</li>
<li><strong>Off / Available</strong>: The system is accessible to the user but is not currently
&quot;On&quot; or has not been configured. If the Indicator directly provides gestures
related to the system, such as opening a configuration dialog box, then use
&quot;Available&quot;; if the user must act elsewhere or the system isn't user-controllable,
use &quot;Off&quot;.</li>
<li><strong>On</strong>: The system is enabled or configured; it is having an effect on the larger application.</li>
<li><strong>Alert / Error</strong>: There has been a problem with the system. Generally, &quot;Alert&quot;
should be used to call attention to an issue that isn't critical, while &quot;Error&quot;
should be used to call attention to a problem that the user should really be aware of or do
something about.</li>
</ul>
<h3>Structure</h3>
<p>Indicators consist of a <code>.ls-indicator</code>
wrapper element with <code>.icon-*</code> classes for the type of thing they represent and
<code>.s-status-*</code> classes to articulate the current state. Title attributes should be used
to provide more verbose information about the thing and/or its status.</p>
<p>The wrapper encloses a <code>.label</code> element that is displayed on hover. This element should
include a brief statement of the current status, and can also include clickable elements
as <code>&lt;a&gt;</code> tags. An optional <code>.count</code> element can be included to display
information such as a number of messages.</p>
<p>Icon classes are as defined on the
<a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">
Glyphs page</a>. Status classes applicable to Indicators are as follows:</p>
<ul>
<li><code>s-status-disabled</code></li>
<li><code>s-status-off</code></li>
<li><code>s-status-available</code></li>
<li><code>s-status-on</code></li>
<li><code>s-status-alert</code></li>
<li><code>s-status-error</code></li>
</ul>
</div>
<mct-example><div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-disabled" title="The system is currently disabled.">
<span class="label">System not enabled.</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-available" title="Configure data connection.">
<span class="label">Data connection available
<a class="icon-gear">Configure</a>
</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-on" title="Data connected.">
<span class="label">Connected to Skynet
<a class="icon-gear">Change</a>
<a>Disconnect</a>
</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-alert" title="System is self-aware.">
<span class="label">Skynet at Turing Level 5</span>
</span>
<span class="ls-indicator icon-bell s-status-error" title="You have alerts.">
<span class="label">
<a class="icon-alert-triangle">View Alerts</a>
</span>
<span class="count">495</span>
</span>
</div>
</mct-example> </mct-example>
</div> </div>
</div> </div>

View File

@@ -54,7 +54,7 @@ define(
return "icon-object-unknown"; return "icon-object-unknown";
}, },
getText: function () { getText: function () {
return "" + latest; return latest;
}, },
getDescription: function () { getDescription: function () {
return ""; return "";

View File

@@ -69,12 +69,11 @@
] ]
})); }));
openmct.install(openmct.plugins.SummaryWidget()); openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook()); openmct.install(openmct.plugins.BarGraph());
openmct.install(openmct.plugins.NotebookV2());
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0}); openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc'); openmct.time.timeSystem('utc');
openmct.start(); openmct.start();
window.openmct = openmct;
}); });
</script> </script>
<link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css"> <link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
@@ -83,6 +82,8 @@
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-96x96.png" sizes="96x96"> <link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-16x16.png" sizes="16x16"> <link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-16x16.png" sizes="16x16">
<link rel="shortcut icon" href="platform/commonUI/general/res/images/favicons/favicon.ico"> <link rel="shortcut icon" href="platform/commonUI/general/res/images/favicons/favicon.ico">
<link rel="stylesheet" href="src/plugins/barGraph/res/styles/barGraph.css">
</head> </head>
<body> <body>
<div class="l-splash-holder s-splash-holder"> <div class="l-splash-holder s-splash-holder">

View File

@@ -37,10 +37,7 @@ module.exports = function(config) {
{pattern: 'bower_components/**/*.js', included: false}, {pattern: 'bower_components/**/*.js', included: false},
{pattern: 'node_modules/d3-*/**/*.js', included: false}, {pattern: 'node_modules/d3-*/**/*.js', included: false},
{pattern: 'node_modules/vue/**/*.js', included: false}, {pattern: 'node_modules/vue/**/*.js', included: false},
{pattern: 'node_modules/printj/dist/*.js', included: false},
{pattern: 'src/**/*', included: false}, {pattern: 'src/**/*', included: false},
{pattern: 'node_modules/painterro/build/*.js', included: false},
{pattern: 'node_modules/html2canvas/dist/*', included: false},
{pattern: 'example/**/*.html', included: false}, {pattern: 'example/**/*.html', included: false},
{pattern: 'example/**/*.js', included: false}, {pattern: 'example/**/*.js', included: false},
{pattern: 'example/**/*.json', included: false}, {pattern: 'example/**/*.json', included: false},
@@ -65,7 +62,7 @@ module.exports = function(config) {
// Test results reporter to use // Test results reporter to use
// Possible values: 'dots', 'progress' // Possible values: 'dots', 'progress'
// Available reporters: https://npmjs.org/browse/keyword/karma-reporter // Available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'html'], reporters: ['progress', 'coverage', 'html', 'junit'],
// Web server port. // Web server port.
port: 9876, port: 9876,
@@ -81,7 +78,7 @@ module.exports = function(config) {
// Specify browsers to run tests in. // Specify browsers to run tests in.
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [ browsers: [
'ChromeHeadless' 'Chrome'
], ],
// Code coverage reporting. // Code coverage reporting.
@@ -104,6 +101,10 @@ module.exports = function(config) {
foldAll: false foldAll: false
}, },
junitReporter: {
outputDir: process.env.CIRCLE_TEST_REPORTS || 'dist/reports/junit'
},
// Continuous Integration mode. // Continuous Integration mode.
// If true, Karma captures browsers, runs the tests and exits. // If true, Karma captures browsers, runs the tests and exits.
singleRun: true singleRun: true

View File

@@ -29,6 +29,7 @@ requirejs.config({
"csv": "bower_components/comma-separated-values/csv.min", "csv": "bower_components/comma-separated-values/csv.min",
"EventEmitter": "bower_components/eventemitter3/index", "EventEmitter": "bower_components/eventemitter3/index",
"es6-promise": "bower_components/es6-promise/es6-promise.min", "es6-promise": "bower_components/es6-promise/es6-promise.min",
"html2canvas": "bower_components/html2canvas/build/html2canvas.min",
"moment": "bower_components/moment/moment", "moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format", "moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"moment-timezone": "bower_components/moment-timezone/builds/moment-timezone-with-data", "moment-timezone": "bower_components/moment-timezone/builds/moment-timezone-with-data",
@@ -48,10 +49,7 @@ requirejs.config({
"d3-format": "node_modules/d3-format/build/d3-format.min", "d3-format": "node_modules/d3-format/build/d3-format.min",
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min", "d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
"d3-time": "node_modules/d3-time/build/d3-time.min", "d3-time": "node_modules/d3-time/build/d3-time.min",
"d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min", "d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min"
"html2canvas": "node_modules/html2canvas/dist/html2canvas.min",
"painterro": "node_modules/painterro/build/painterro.min",
"printj": "node_modules/printj/dist/printj.min"
}, },
"shim": { "shim": {
"angular": { "angular": {
@@ -63,12 +61,12 @@ requirejs.config({
"EventEmitter": { "EventEmitter": {
"exports": "EventEmitter" "exports": "EventEmitter"
}, },
"html2canvas": {
"exports": "html2canvas"
},
"moment-duration-format": { "moment-duration-format": {
"deps": ["moment"] "deps": ["moment"]
}, },
"painterro": {
"exports": "Painterro"
},
"saveAs": { "saveAs": {
"exports": "saveAs" "exports": "saveAs"
}, },
@@ -90,9 +88,6 @@ requirejs.config({
}, },
"d3-axis": { "d3-axis": {
"exports": "d3-axis" "exports": "d3-axis"
},
"dom-to-image": {
"exports": "domtoimage"
} }
} }
}); });

View File

@@ -15,7 +15,6 @@
"d3-time-format": "2.1.x", "d3-time-format": "2.1.x",
"express": "^4.13.1", "express": "^4.13.1",
"minimist": "^1.1.1", "minimist": "^1.1.1",
"painterro": "^0.2.65",
"request": "^2.69.0", "request": "^2.69.0",
"vue": "^2.5.6" "vue": "^2.5.6"
}, },
@@ -31,18 +30,18 @@
"gulp-requirejs-optimize": "^0.3.1", "gulp-requirejs-optimize": "^0.3.1",
"gulp-sass": "^3.1.0", "gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^1.6.0", "gulp-sourcemaps": "^1.6.0",
"html2canvas": "^1.0.0-alpha.12", "jasmine-core": "^2.3.0",
"jasmine-core": "^3.1.0",
"jscs-html-reporter": "^0.1.0", "jscs-html-reporter": "^0.1.0",
"jsdoc": "^3.3.2", "jsdoc": "^3.3.2",
"jshint": "^2.7.0", "jshint": "^2.7.0",
"karma": "^2.0.3", "karma": "^0.13.3",
"karma-chrome-launcher": "^2.2.0", "karma-chrome-launcher": "^0.1.12",
"karma-cli": "^1.0.1", "karma-cli": "0.0.4",
"karma-coverage": "^1.1.2", "karma-coverage": "^0.5.3",
"karma-html-reporter": "^0.2.7", "karma-html-reporter": "^0.2.7",
"karma-jasmine": "^1.1.2", "karma-jasmine": "^0.1.5",
"karma-requirejs": "^1.1.0", "karma-junit-reporter": "^0.3.8",
"karma-requirejs": "^0.2.2",
"lodash": "^3.10.1", "lodash": "^3.10.1",
"markdown-toc": "^0.11.7", "markdown-toc": "^0.11.7",
"marked": "^0.3.5", "marked": "^0.3.5",
@@ -50,7 +49,6 @@
"mkdirp": "^0.5.1", "mkdirp": "^0.5.1",
"moment": "^2.11.1", "moment": "^2.11.1",
"node-bourbon": "^4.2.3", "node-bourbon": "^4.2.3",
"printj": "^1.1.0",
"requirejs": "2.1.x", "requirejs": "2.1.x",
"split": "^1.0.0", "split": "^1.0.0",
"v8-compile-cache": "^1.1.0" "v8-compile-cache": "^1.1.0"

View File

@@ -65,7 +65,7 @@
<div class='split-pane-component t-object pane primary-pane left'> <div class='split-pane-component t-object pane primary-pane left'>
<mct-representation mct-object="navigatedObject" <mct-representation mct-object="navigatedObject"
key="navigatedObject.getCapability('status').get('editing') ? 'edit-object' : 'browse-object'" key="navigatedObject.getCapability('status').get('editing') ? 'edit-object' : 'browse-object'"
class="abs holder holder-object t-main-view"> class="abs holder holder-object">
</mct-representation> </mct-representation>
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect flush-right" <a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect flush-right"
title="{{ modelPaneInspect.visible()? 'Hide' : 'Show' }} the Inspection pane" title="{{ modelPaneInspect.visible()? 'Hide' : 'Show' }} the Inspection pane"

View File

@@ -19,46 +19,41 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<div ng-controller="ObjectInspectorController as controller" class="grid-properties"> <div ng-controller="ObjectInspectorController as controller">
<ul class="l-inspector-part"> <ul class="flex-elem grows l-inspector-part">
<h2 class="first">Properties</h2> <li>
<li class="t-repeat grid-row" <em class="t-inspector-part-header">Properties</em>
ng-repeat="data in metadata" <div class="inspector-properties"
ng-class="{ first:$index === 0 }"> ng-repeat="data in metadata"
<div class="grid-cell label">{{ data.name }}</div> ng-class="{ first:$index === 0 }">
<div class="grid-cell value">{{ data.value }}</div> <div class="label">{{ data.name }}</div>
</li> <div class="value">{{ data.value }}</div>
</ul>
<ul class="l-inspector-part" ng-if="contextutalParents.length > 0">
<h2 title="The location of this linked object.">Location</h2>
<li class="grid-row">
<div class="label" ng-if="primaryParents.length > 0">This Link</div>
<div class="grid-cell value">
<div class="t-repeat inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</div>
</div> </div>
</li> </li>
<li class="grid-row" ng-if="primaryParents.length > 0"> <li ng-if="contextutalParents.length > 0">
<div class="grid-cell label">Original</div> <em class="t-inspector-part-header" title="The location of this linked object.">Location</em>
<div class="grid-cell value"> <div ng-if="primaryParents.length > 0" class="section-header">This Object</div>
<div class="t-repeat inspector-location value" <span class="inspector-location"
ng-repeat="parent in primaryParents" ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === primaryParents.length }"> ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'" <mct-representation key="'label'"
mct-object="parent" mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')" ng-click="parent.getCapability('action').perform('navigate')"
class="location-item"> class="location-item">
</mct-representation> </mct-representation>
</div> </span>
</div> </li>
<li ng-if="primaryParents.length > 0">
<div class="section-header">Object's Original</div>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</span>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -47,8 +47,8 @@ define(
urlService, urlService,
defaultPath defaultPath
) { ) {
var initialPath = ($route.current.params.ids || defaultPath).split("/"), var initialPath = ($route.current.params.ids || defaultPath).split("/");
currentIds; var currentIds;
$scope.treeModel = { $scope.treeModel = {
selectedObject: undefined, selectedObject: undefined,
@@ -56,24 +56,7 @@ define(
navigationService.setNavigation(object, true); navigationService.setNavigation(object, true);
}, },
allowSelection: function (object) { allowSelection: function (object) {
var domainObjectInView = navigationService.getNavigation(), return navigationService.shouldNavigate();
isInEditMode = domainObjectInView.getCapability('status').get('editing');
if (isInEditMode) {
var actions = object.getCapability('action'),
previewAction = actions.getActions({key: 'mct-preview-action'})[0];
if (previewAction && previewAction.perform) {
previewAction.perform();
return false;
} else {
return navigationService.shouldNavigate();
}
} else {
return true;
}
} }
}; };

View File

@@ -162,6 +162,7 @@ define(
*/ */
NavigationService.prototype.shouldWarnBeforeNavigate = function () { NavigationService.prototype.shouldWarnBeforeNavigate = function () {
var reasons = []; var reasons = [];
this.checks.forEach(function (checkFn) { this.checks.forEach(function (checkFn) {
var reason = checkFn(); var reason = checkFn();
if (reason) { if (reason) {

View File

@@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global console*/
/** /**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14. * MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
@@ -49,19 +48,9 @@ define(
controller; controller;
function waitsForNavigation() { function waitsForNavigation() {
return new Promise(function (resolve) { var calls = mockNavigationService.setNavigation.calls.length;
mockNavigationService.setNavigation.and.callFake(function (obj) { waitsFor(function () {
var returnValue; return mockNavigationService.setNavigation.calls.length > calls;
try {
returnValue = NavigationService.prototype.setNavigation.call(mockNavigationService, obj);
} catch (err) {
console.error(err);
//Not rejecting because 'setNavigation' has been called, which is what's being tested here.
//Rejecting will fail tests.
}
resolve();
return returnValue;
});
}); });
} }
@@ -89,7 +78,7 @@ define(
"urlService", "urlService",
["urlForLocation"] ["urlForLocation"]
); );
mockUrlService.urlForLocation.and.callFake(function (mode, object) { mockUrlService.urlForLocation.andCallFake(function (mode, object) {
if (object === mockDefaultRootObject) { if (object === mockDefaultRootObject) {
return [mode, testDefaultRoot].join('/'); return [mode, testDefaultRoot].join('/');
} }
@@ -117,7 +106,7 @@ define(
"removeListener" "removeListener"
].forEach(function (method) { ].forEach(function (method) {
spyOn(mockNavigationService, method) spyOn(mockNavigationService, method)
.and.callThrough(); .andCallThrough();
}); });
mockRootObject = jasmine.createSpyObj( mockRootObject = jasmine.createSpyObj(
"rootObjectContainer", "rootObjectContainer",
@@ -135,58 +124,60 @@ define(
"nestedDomainObject", "nestedDomainObject",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"] ["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
); );
mockObjectService.getObjects.and.returnValue(Promise.resolve({ mockObjectService.getObjects.andReturn(Promise.resolve({
ROOT: mockRootObject ROOT: mockRootObject
})); }));
mockRootObject.useCapability.and.returnValue(Promise.resolve([ mockRootObject.useCapability.andReturn(Promise.resolve([
mockOtherDomainObject, mockOtherDomainObject,
mockDefaultRootObject mockDefaultRootObject
])); ]));
mockRootObject.hasCapability.and.returnValue(true); mockRootObject.hasCapability.andReturn(true);
mockDefaultRootObject.useCapability.and.returnValue(Promise.resolve([ mockDefaultRootObject.useCapability.andReturn(Promise.resolve([
mockNextObject mockNextObject
])); ]));
mockDefaultRootObject.hasCapability.and.returnValue(true); mockDefaultRootObject.hasCapability.andReturn(true);
mockOtherDomainObject.hasCapability.and.returnValue(false); mockOtherDomainObject.hasCapability.andReturn(false);
mockNextObject.useCapability.and.returnValue(undefined); mockNextObject.useCapability.andReturn(undefined);
mockNextObject.hasCapability.and.returnValue(false); mockNextObject.hasCapability.andReturn(false);
mockNextObject.getId.and.returnValue("next"); mockNextObject.getId.andReturn("next");
mockDefaultRootObject.getId.and.returnValue(testDefaultRoot); mockDefaultRootObject.getId.andReturn(testDefaultRoot);
instantiateController(); instantiateController();
return waitsForNavigation(); waitsForNavigation();
}); });
it("uses composition to set the navigated object, if there is none", function () { it("uses composition to set the navigated object, if there is none", function () {
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
runs(function () {
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject); .toHaveBeenCalledWith(mockDefaultRootObject);
}); });
}); });
it("navigates to a root-level object, even when default path is not found", function () { it("navigates to a root-level object, even when default path is not found", function () {
mockDefaultRootObject.getId mockDefaultRootObject.getId
.and.returnValue("something-other-than-the-" + testDefaultRoot); .andReturn("something-other-than-the-" + testDefaultRoot);
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
runs(function () {
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject); .toHaveBeenCalledWith(mockDefaultRootObject);
}); });
});
});
//
it("does not try to override navigation", function () { it("does not try to override navigation", function () {
mockNavigationService.getNavigation.and.returnValue(mockDefaultRootObject); mockNavigationService.getNavigation.andReturn(mockDefaultRootObject);
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject); expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
});
}); });
//
it("updates scope when navigated object changes", function () { it("updates scope when navigated object changes", function () {
// Should have registered a listener - call it // Should have registered a listener - call it
mockNavigationService.addListener.calls.mostRecent().args[0]( mockNavigationService.addListener.mostRecentCall.args[0](
mockOtherDomainObject mockOtherDomainObject
); );
expect(mockScope.navigatedObject).toEqual(mockOtherDomainObject); expect(mockScope.navigatedObject).toEqual(mockOtherDomainObject);
@@ -198,18 +189,19 @@ define(
"$destroy", "$destroy",
jasmine.any(Function) jasmine.any(Function)
); );
mockScope.$on.calls.mostRecent().args[1](); mockScope.$on.mostRecentCall.args[1]();
// Should remove the listener it added earlier // Should remove the listener it added earlier
expect(mockNavigationService.removeListener).toHaveBeenCalledWith( expect(mockNavigationService.removeListener).toHaveBeenCalledWith(
mockNavigationService.addListener.calls.mostRecent().args[0] mockNavigationService.addListener.mostRecentCall.args[0]
); );
}); });
it("uses route parameters to choose initially-navigated object", function () { it("uses route parameters to choose initially-navigated object", function () {
mockRoute.current.params.ids = testDefaultRoot + "/next"; mockRoute.current.params.ids = testDefaultRoot + "/next";
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject); expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject); .toHaveBeenCalledWith(mockNextObject);
@@ -222,10 +214,12 @@ define(
// it hits an invalid ID. // it hits an invalid ID.
mockRoute.current.params.ids = testDefaultRoot + "/junk"; mockRoute.current.params.ids = testDefaultRoot + "/junk";
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject); expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject); .toHaveBeenCalledWith(mockDefaultRootObject);
}); });
}); });
@@ -235,7 +229,8 @@ define(
// should stop at it since remaining IDs cannot be loaded. // should stop at it since remaining IDs cannot be loaded.
mockRoute.current.params.ids = testDefaultRoot + "/next/junk"; mockRoute.current.params.ids = testDefaultRoot + "/next/junk";
instantiateController(); instantiateController();
return waitsForNavigation().then(function () { waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject); expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject); .toHaveBeenCalledWith(mockNextObject);
@@ -249,11 +244,11 @@ define(
expect(mockRoute.current.pathParams.ids) expect(mockRoute.current.pathParams.ids)
.not .not
.toBe(testDefaultRoot + '/next'); .toBe(testDefaultRoot + '/next');
mockLocation.path.and.callFake(function () { mockLocation.path.andCallFake(function () {
expect(mockRoute.current.pathParams.ids) expect(mockRoute.current.pathParams.ids)
.toBe(testDefaultRoot + '/next'); .toBe(testDefaultRoot + '/next');
}); });
mockNavigationService.addListener.calls.mostRecent().args[0]( mockNavigationService.addListener.mostRecentCall.args[0](
mockNextObject mockNextObject
); );
expect(mockLocation.path).toHaveBeenCalledWith( expect(mockLocation.path).toHaveBeenCalledWith(

View File

@@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
define( define(
["../src/BrowseObjectController"], ["../src/BrowseObjectController"],
function (BrowseObjectController) { function (BrowseObjectController) {
@@ -32,7 +33,7 @@ define(
// Utility function; look for a $watch on scope and fire it // Utility function; look for a $watch on scope and fire it
function fireWatch(expr, value) { function fireWatch(expr, value) {
mockScope.$watch.calls.all().forEach(function (call) { mockScope.$watch.calls.forEach(function (call) {
if (call.args[0] === expr) { if (call.args[0] === expr) {
call.args[1](value); call.args[1](value);
} }
@@ -49,7 +50,7 @@ define(
"$location", "$location",
["path", "search"] ["path", "search"]
); );
mockLocation.search.and.returnValue({}); mockLocation.search.andReturn({});
controller = new BrowseObjectController( controller = new BrowseObjectController(
mockScope, mockScope,
@@ -64,7 +65,7 @@ define(
// Allows the path index to be checked // Allows the path index to be checked
// prior to setting $route.current // prior to setting $route.current
mockLocation.path.and.returnValue("/browse/"); mockLocation.path.andReturn("/browse/");
}); });
it("sets the active view from query parameters", function () { it("sets the active view from query parameters", function () {
@@ -78,10 +79,10 @@ define(
{ key: 'xyz' } { key: 'xyz' }
]; ];
mockDomainObject.useCapability.and.callFake(function (c) { mockDomainObject.useCapability.andCallFake(function (c) {
return (c === 'view') && testViews; return (c === 'view') && testViews;
}); });
mockLocation.search.and.returnValue({ view: 'def' }); mockLocation.search.andReturn({ view: 'def' });
fireWatch('domainObject', mockDomainObject); fireWatch('domainObject', mockDomainObject);
expect(mockScope.representation.selected) expect(mockScope.representation.selected)

View File

@@ -50,14 +50,14 @@ define(
"navigationService", "navigationService",
["getNavigation", "addListener"] ["getNavigation", "addListener"]
); );
mockNavigationService.addListener.and.returnValue(mockNavigationUnlistener); mockNavigationService.addListener.andReturn(mockNavigationUnlistener);
mockStatusUnlistener = jasmine.createSpy("statusUnlistener"); mockStatusUnlistener = jasmine.createSpy("statusUnlistener");
mockStatusCapability = jasmine.createSpyObj( mockStatusCapability = jasmine.createSpyObj(
"statusCapability", "statusCapability",
["listen"] ["listen"]
); );
mockStatusCapability.listen.and.returnValue(mockStatusUnlistener); mockStatusCapability.listen.andReturn(mockStatusUnlistener);
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
'domainObject', 'domainObject',
@@ -68,13 +68,13 @@ define(
'hasCapability' 'hasCapability'
] ]
); );
mockDomainObject.getId.and.returnValue("domainObject"); mockDomainObject.getId.andReturn("domainObject");
mockDomainObject.getModel.and.returnValue({}); mockDomainObject.getModel.andReturn({});
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.and.returnValue(mockStatusCapability); mockDomainObject.getCapability.andReturn(mockStatusCapability);
mockLocation = jasmine.createSpyObj('location', ['search']); mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({}); mockLocation.search.andReturn({});
mockAttrs = {}; mockAttrs = {};
@@ -84,7 +84,7 @@ define(
it("listens for changes to navigation and attaches a status" + it("listens for changes to navigation and attaches a status" +
" listener", function () { " listener", function () {
expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function)); expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function));
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject); mockNavigationService.addListener.mostRecentCall.args[0](mockDomainObject);
expect(mockStatusCapability.listen).toHaveBeenCalledWith(jasmine.any(Function)); expect(mockStatusCapability.listen).toHaveBeenCalledWith(jasmine.any(Function));
}); });
@@ -93,8 +93,8 @@ define(
controller.toggle(); controller.toggle();
// test pre-condition that inspector is hidden // test pre-condition that inspector is hidden
expect(controller.visible()).toBe(false); expect(controller.visible()).toBe(false);
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject); mockNavigationService.addListener.mostRecentCall.args[0](mockDomainObject);
mockStatusCapability.listen.calls.mostRecent().args[0](["editing"]); mockStatusCapability.listen.mostRecentCall.args[0](["editing"]);
expect(controller.visible()).toBe(true); expect(controller.visible()).toBe(true);
}); });

View File

@@ -60,8 +60,8 @@ define(
mockActionContext.domainObject = mockDomainObject; mockActionContext.domainObject = mockDomainObject;
mockActionContext.event = mockEvent; mockActionContext.event = mockEvent;
mockScope.domainObject = mockDomainObject; mockScope.domainObject = mockDomainObject;
mockDomainObject.getCapability.and.returnValue(mockContextMenuAction); mockDomainObject.getCapability.andReturn(mockContextMenuAction);
mockContextMenuAction.perform.and.returnValue(jasmine.any(Function)); mockContextMenuAction.perform.andReturn(jasmine.any(Function));
controller = new MenuArrowController(mockScope); controller = new MenuArrowController(mockScope);
}); });

View File

@@ -39,7 +39,7 @@ define(
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]); mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]); mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]);
mockTypeCapability.typeDef = { name: ""}; mockTypeCapability.typeDef = { name: ""};
mockTypeCapability.hasFeature.and.callFake(function (feature) { mockTypeCapability.hasFeature.andCallFake(function (feature) {
return feature === 'creation'; return feature === 'creation';
}); });
@@ -52,8 +52,8 @@ define(
name: "Test name" name: "Test name"
}; };
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]); mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]);
mockDomainObject.getModel.and.returnValue(model); mockDomainObject.getModel.andReturn(model);
mockDomainObject.getCapability.and.callFake(function (key) { mockDomainObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key]; return mockCapabilities[key];
}); });
@@ -62,7 +62,7 @@ define(
}; };
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]); mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]);
mockCurrentTarget.blur.and.returnValue(mockCurrentTarget); mockCurrentTarget.blur.andReturn(mockCurrentTarget);
mockEvent = { mockEvent = {
which: {}, which: {},
@@ -109,7 +109,7 @@ define(
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function)); expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
mockMutationCapability.mutate.calls.mostRecent().args[0](model); mockMutationCapability.mutate.mostRecentCall.args[0](model);
expect(mockDomainObject.getModel().name).toBe("New name"); expect(mockDomainObject.getModel().name).toBe("New name");
}); });
@@ -127,7 +127,7 @@ define(
}); });
it("disallows editting name when object is non-creatable", function () { it("disallows editting name when object is non-creatable", function () {
mockTypeCapability.hasFeature.and.returnValue(false); mockTypeCapability.hasFeature.andReturn(false);
expect(controller.allowEdit()).toBe(false); expect(controller.allowEdit()).toBe(false);

View File

@@ -53,8 +53,8 @@ define(
['getId', 'getModel', 'getCapability'] ['getId', 'getModel', 'getCapability']
); );
mockDomainObject.getId.and.returnValue(id); mockDomainObject.getId.andReturn(id);
mockDomainObject.getModel.and.returnValue({}); mockDomainObject.getModel.andReturn({});
return mockDomainObject; return mockDomainObject;
}); });
@@ -65,7 +65,7 @@ define(
mockWindow = jasmine.createSpyObj("$window", ["open"]); mockWindow = jasmine.createSpyObj("$window", ["open"]);
mockLocation = jasmine.createSpyObj('location', ['search']); mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({}); mockLocation.search.andReturn({});
mockAttrs = {}; mockAttrs = {};
}); });
@@ -83,9 +83,9 @@ define(
}); });
it("collapses on navigation changes on portrait-oriented phones", function () { it("collapses on navigation changes on portrait-oriented phones", function () {
mockAgentService.isMobile.and.returnValue(true); mockAgentService.isMobile.andReturn(true);
mockAgentService.isPhone.and.returnValue(true); mockAgentService.isPhone.andReturn(true);
mockAgentService.isPortrait.and.returnValue(true); mockAgentService.isPortrait.andReturn(true);
controller = instantiateController(); controller = instantiateController();
expect(controller.visible()).toBeTruthy(); expect(controller.visible()).toBeTruthy();
@@ -102,13 +102,13 @@ define(
}); });
it("sets pane state to false when in location.search", function () { it("sets pane state to false when in location.search", function () {
mockLocation.search.and.returnValue({'hideTree': true}); mockLocation.search.andReturn({'hideTree': true});
expect(instantiateController().visible()).toBe(false); expect(instantiateController().visible()).toBe(false);
expect(mockLocation.search).toHaveBeenCalledWith('hideTree', undefined); expect(mockLocation.search).toHaveBeenCalledWith('hideTree', undefined);
}); });
it("sets state to true when not found in location.search", function () { it("sets state to true when not found in location.search", function () {
mockLocation.search.and.returnValue({}); mockLocation.search.andReturn({});
expect(instantiateController().visible()).toBe(true); expect(instantiateController().visible()).toBe(true);
expect(mockLocation.search).not.toHaveBeenCalledWith('hideTree', undefined); expect(mockLocation.search).not.toHaveBeenCalledWith('hideTree', undefined);
}); });

View File

@@ -34,6 +34,17 @@ define([
mockDomainObject, mockDomainObject,
action; action;
function waitForCall() {
var called = false;
waitsFor(function () {
return called;
});
return function () {
called = true;
};
}
beforeEach(function () { beforeEach(function () {
mockNavigationService = jasmine.createSpyObj( mockNavigationService = jasmine.createSpyObj(
"navigationService", "navigationService",
@@ -52,24 +63,26 @@ define([
}); });
it("sets navigation if it is allowed", function () { it("sets navigation if it is allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(true); mockNavigationService.shouldNavigate.andReturn(true);
return action.perform() action.perform()
.then(function () { .then(waitForCall());
expect(mockNavigationService.setNavigation) runs(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject, true); .toHaveBeenCalledWith(mockDomainObject, true);
}); });
}); });
it("does not set navigation if it is not allowed", function () { it("does not set navigation if it is not allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(false); mockNavigationService.shouldNavigate.andReturn(false);
var onSuccess = jasmine.createSpy('onSuccess'); var onSuccess = jasmine.createSpy('onSuccess');
return action.perform() action.perform()
.then(onSuccess, function () { .then(onSuccess, waitForCall());
expect(onSuccess).not.toHaveBeenCalled(); runs(function () {
expect(mockNavigationService.setNavigation) expect(onSuccess).not.toHaveBeenCalled();
.not expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject); .not
}); .toHaveBeenCalledWith(mockDomainObject);
});
}); });
it("is only applicable when a domain object is in context", function () { it("is only applicable when a domain object is in context", function () {

View File

@@ -69,7 +69,7 @@ define(
navigationService.addListener(callback); navigationService.addListener(callback);
navigationService.setNavigation(testObject); navigationService.setNavigation(testObject);
navigationService.setNavigation(testObject); navigationService.setNavigation(testObject);
expect(callback.calls.count()).toEqual(1); expect(callback.calls.length).toEqual(1);
}); });
it("stops notifying listeners after removal", function () { it("stops notifying listeners after removal", function () {

View File

@@ -65,35 +65,34 @@ define([
mockActionCapability = jasmine.createSpyObj('action', ['perform']); mockActionCapability = jasmine.createSpyObj('action', ['perform']);
mockEditor = jasmine.createSpyObj('editor', ['isEditContextRoot']); mockEditor = jasmine.createSpyObj('editor', ['isEditContextRoot']);
mockThrottle.and.callFake(function (fn) { mockThrottle.andCallFake(function (fn) {
var mockThrottledFn = var mockThrottledFn =
jasmine.createSpy('throttled-' + mockThrottledFns.length); jasmine.createSpy('throttled-' + mockThrottledFns.length);
mockThrottledFn.and.callFake(fn); mockThrottledFn.andCallFake(fn);
mockThrottledFns.push(mockThrottledFn); mockThrottledFns.push(mockThrottledFn);
return mockThrottledFn; return mockThrottledFn;
}); });
mockTopic.and.returnValue(mockMutationTopic); mockTopic.andReturn(mockMutationTopic);
mockDomainObject.getId.and.returnValue(testId); mockDomainObject.getId.andReturn(testId);
mockDomainObject.getCapability.and.callFake(function (c) { mockDomainObject.getCapability.andCallFake(function (c) {
return { return {
context: mockContext, context: mockContext,
editor: mockEditor editor: mockEditor
}[c]; }[c];
}); });
mockDomainObject.hasCapability.and.callFake(function (c) { mockDomainObject.hasCapability.andCallFake(function (c) {
return !!mockDomainObject.getCapability(c); return !!mockDomainObject.getCapability(c);
}); });
mockParentObject.getCapability.and.callFake(function (c) { mockParentObject.getCapability.andCallFake(function (c) {
return { return {
action: mockActionCapability action: mockActionCapability
}[c]; }[c];
}); });
testParentComposition = []; testParentComposition = [];
mockParentObject.useCapability.and.returnValue(Promise.resolve(testParentComposition)); mockParentObject.useCapability.andReturn(Promise.resolve(testParentComposition));
mockContext.getParent.andReturn(mockParentObject);
mockContext.getParent.and.returnValue(mockParentObject); mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockNavigationService.getNavigation.and.returnValue(mockDomainObject); mockEditor.isEditContextRoot.andReturn(false);
mockEditor.isEditContextRoot.and.returnValue(false);
return new OrphanNavigationHandler( return new OrphanNavigationHandler(
mockThrottle, mockThrottle,
@@ -107,7 +106,7 @@ define([
expect(mockMutationTopic.listen) expect(mockMutationTopic.listen)
.toHaveBeenCalledWith(jasmine.any(Function)); .toHaveBeenCalledWith(jasmine.any(Function));
expect(mockThrottledFns.indexOf( expect(mockThrottledFns.indexOf(
mockMutationTopic.listen.calls.mostRecent().args[0] mockMutationTopic.listen.mostRecentCall.args[0]
)).not.toEqual(-1); )).not.toEqual(-1);
}); });
@@ -115,7 +114,7 @@ define([
expect(mockNavigationService.addListener) expect(mockNavigationService.addListener)
.toHaveBeenCalledWith(jasmine.any(Function)); .toHaveBeenCalledWith(jasmine.any(Function));
expect(mockThrottledFns.indexOf( expect(mockThrottledFns.indexOf(
mockNavigationService.addListener.calls.mostRecent().args[0] mockNavigationService.addListener.mostRecentCall.args[0]
)).not.toEqual(-1); )).not.toEqual(-1);
}); });
@@ -135,14 +134,28 @@ define([
function itNavigatesAsExpected() { function itNavigatesAsExpected() {
if (isOrphan && !isEditRoot) { if (isOrphan && !isEditRoot) {
it("navigates to the parent", function () { it("navigates to the parent", function () {
return Promise.resolve().then(function () { var done = false;
waitsFor(function () {
return done;
});
setTimeout(function () {
done = true;
}, 5);
runs(function () {
expect(mockActionCapability.perform) expect(mockActionCapability.perform)
.toHaveBeenCalledWith('navigate'); .toHaveBeenCalledWith('navigate');
}); });
}); });
} else { } else {
it("does nothing", function () { it("does nothing", function () {
return Promise.resolve().then(function () { var done = false;
waitsFor(function () {
return done;
});
setTimeout(function () {
done = true;
}, 5);
runs(function () {
expect(mockActionCapability.perform) expect(mockActionCapability.perform)
.not.toHaveBeenCalled(); .not.toHaveBeenCalled();
}); });
@@ -152,12 +165,12 @@ define([
describe(caseName, function () { describe(caseName, function () {
beforeEach(function () { beforeEach(function () {
mockEditor.isEditContextRoot.and.returnValue(isEditRoot); mockEditor.isEditContextRoot.andReturn(isEditRoot);
}); });
describe("when navigation changes", function () { describe("when navigation changes", function () {
beforeEach(function () { beforeEach(function () {
mockNavigationService.addListener.calls.mostRecent() mockNavigationService.addListener.mostRecentCall
.args[0](mockDomainObject); .args[0](mockDomainObject);
}); });
itNavigatesAsExpected(); itNavigatesAsExpected();
@@ -165,7 +178,7 @@ define([
describe("when mutation occurs", function () { describe("when mutation occurs", function () {
beforeEach(function () { beforeEach(function () {
mockMutationTopic.listen.calls.mostRecent() mockMutationTopic.listen.mostRecentCall
.args[0](mockParentObject); .args[0](mockParentObject);
}); });

View File

@@ -49,8 +49,8 @@ define(
); );
mockDocument = [{}]; mockDocument = [{}];
mockDomainObject.getModel.and.returnValue({ name: 'Test name' }); mockDomainObject.getModel.andReturn({ name: 'Test name' });
mockNavigationService.getNavigation.and.returnValue(mockDomainObject); mockNavigationService.getNavigation.andReturn(mockDomainObject);
titler = new WindowTitler( titler = new WindowTitler(
mockNavigationService, mockNavigationService,
@@ -64,12 +64,12 @@ define(
jasmine.any(Function), jasmine.any(Function),
jasmine.any(Function) jasmine.any(Function)
); );
expect(mockRootScope.$watch.calls.mostRecent().args[0]()) expect(mockRootScope.$watch.mostRecentCall.args[0]())
.toEqual('Test name'); .toEqual('Test name');
}); });
it("sets the title to the name of the navigated object", function () { it("sets the title to the name of the navigated object", function () {
mockRootScope.$watch.calls.mostRecent().args[1]("Some name"); mockRootScope.$watch.mostRecentCall.args[1]("Some name");
expect(mockDocument[0].title).toEqual("Some name"); expect(mockDocument[0].title).toEqual("Some name");
}); });

View File

@@ -4,10 +4,7 @@
<div class="top-bar"> <div class="top-bar">
<div class="title">{{ngModel.title}}</div> <div class="title">{{ngModel.title}}</div>
</div> </div>
<div class="hint" ng-hide="ngModel.hint === undefined"> <div class="hint" ng-hide="ngModel.hint === undefined">{{ngModel.hint}}</div>
{{ngModel.hint}}
<span ng-if="ngModel.timestamp !== undefined">[{{ngModel.timestamp}}]</span>
</div>
<div class="message-body"> <div class="message-body">
<div class="message-action"> <div class="message-action">
{{ngModel.actionText}} {{ngModel.actionText}}

View File

@@ -63,12 +63,12 @@ define(
["find"] ["find"]
); );
mockBody = jasmine.createSpyObj('body', ['on', 'off']); mockBody = jasmine.createSpyObj('body', ['on', 'off']);
mockDocument.find.and.returnValue(mockBody); mockDocument.find.andReturn(mockBody);
mockDeferred.promise = "mock promise"; mockDeferred.promise = "mock promise";
mockQ.defer.and.returnValue(mockDeferred); mockQ.defer.andReturn(mockDeferred);
mockOverlayService.createOverlay.and.returnValue(mockOverlay); mockOverlayService.createOverlay.andReturn(mockOverlay);
dialogService = new DialogService( dialogService = new DialogService(
mockOverlayService, mockOverlayService,
@@ -85,7 +85,7 @@ define(
it("allows user input to be canceled", function () { it("allows user input to be canceled", function () {
dialogService.getUserInput({}, { someKey: "some value" }); dialogService.getUserInput({}, { someKey: "some value" });
mockOverlayService.createOverlay.calls.mostRecent().args[1].cancel(); mockOverlayService.createOverlay.mostRecentCall.args[1].cancel();
expect(mockDeferred.reject).toHaveBeenCalled(); expect(mockDeferred.reject).toHaveBeenCalled();
expect(mockDeferred.resolve).not.toHaveBeenCalled(); expect(mockDeferred.resolve).not.toHaveBeenCalled();
}); });
@@ -93,7 +93,7 @@ define(
it("passes back the result of user input when confirmed", function () { it("passes back the result of user input when confirmed", function () {
var value = { someKey: 42 }; var value = { someKey: 42 };
dialogService.getUserInput({}, value); dialogService.getUserInput({}, value);
mockOverlayService.createOverlay.calls.mostRecent().args[1].confirm(); mockOverlayService.createOverlay.mostRecentCall.args[1].confirm();
expect(mockDeferred.reject).not.toHaveBeenCalled(); expect(mockDeferred.reject).not.toHaveBeenCalled();
expect(mockDeferred.resolve).toHaveBeenCalledWith(value); expect(mockDeferred.resolve).toHaveBeenCalledWith(value);
}); });
@@ -109,7 +109,7 @@ define(
it("can show multiple dialogs if prior ones are dismissed", function () { it("can show multiple dialogs if prior ones are dismissed", function () {
dialogService.getUserInput({}, {}); dialogService.getUserInput({}, {});
expect(mockLog.warn).not.toHaveBeenCalled(); expect(mockLog.warn).not.toHaveBeenCalled();
mockOverlayService.createOverlay.calls.mostRecent().args[1].confirm(); mockOverlayService.createOverlay.mostRecentCall.args[1].confirm();
dialogService.getUserInput({}, {}); dialogService.getUserInput({}, {});
expect(mockLog.warn).not.toHaveBeenCalled(); expect(mockLog.warn).not.toHaveBeenCalled();
expect(mockDeferred.reject).not.toHaveBeenCalled(); expect(mockDeferred.reject).not.toHaveBeenCalled();
@@ -148,13 +148,13 @@ define(
it("destroys the event listener when the dialog is cancelled", function () { it("destroys the event listener when the dialog is cancelled", function () {
dialogService.getUserInput({}, {}); dialogService.getUserInput({}, {});
mockOverlayService.createOverlay.calls.mostRecent().args[1].cancel(); mockOverlayService.createOverlay.mostRecentCall.args[1].cancel();
expect(mockBody.off).toHaveBeenCalledWith("keydown", jasmine.any(Function)); expect(mockBody.off).toHaveBeenCalledWith("keydown", jasmine.any(Function));
}); });
it("cancels the dialog when an escape keydown event is triggered", function () { it("cancels the dialog when an escape keydown event is triggered", function () {
dialogService.getUserInput({}, {}); dialogService.getUserInput({}, {});
mockBody.on.calls.mostRecent().args[1]({ mockBody.on.mostRecentCall.args[1]({
keyCode: 27 keyCode: 27
}); });
expect(mockDeferred.reject).toHaveBeenCalled(); expect(mockDeferred.reject).toHaveBeenCalled();
@@ -163,7 +163,7 @@ define(
it("ignores non escape keydown events", function () { it("ignores non escape keydown events", function () {
dialogService.getUserInput({}, {}); dialogService.getUserInput({}, {});
mockBody.on.calls.mostRecent().args[1]({ mockBody.on.mostRecentCall.args[1]({
keyCode: 13 keyCode: 13
}); });
expect(mockDeferred.reject).not.toHaveBeenCalled(); expect(mockDeferred.reject).not.toHaveBeenCalled();
@@ -197,7 +197,7 @@ define(
"overlay", "overlay",
["dismiss"] ["dismiss"]
); );
mockOverlayService.createOverlay.and.returnValue(secondMockOverlay); mockOverlayService.createOverlay.andReturn(secondMockOverlay);
secondDialogHandle = dialogService.showBlockingMessage(dialogModel); secondDialogHandle = dialogService.showBlockingMessage(dialogModel);
//Dismiss the first dialog. It should only dismiss if it //Dismiss the first dialog. It should only dismiss if it

View File

@@ -46,10 +46,10 @@ define(
mockElement = jasmine.createSpyObj("element", ["remove"]); mockElement = jasmine.createSpyObj("element", ["remove"]);
mockScope = jasmine.createSpyObj("scope", ["$destroy"]); mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockDocument.find.and.returnValue(mockBody); mockDocument.find.andReturn(mockBody);
mockCompile.and.returnValue(mockTemplate); mockCompile.andReturn(mockTemplate);
mockRootScope.$new.and.returnValue(mockScope); mockRootScope.$new.andReturn(mockScope);
mockTemplate.and.returnValue(mockElement); mockTemplate.andReturn(mockElement);
overlayService = new OverlayService( overlayService = new OverlayService(
mockDocument, mockDocument,
@@ -61,7 +61,7 @@ define(
it("prepends an mct-include to create overlays", function () { it("prepends an mct-include to create overlays", function () {
overlayService.createOverlay("test", {}); overlayService.createOverlay("test", {});
expect(mockCompile).toHaveBeenCalled(); expect(mockCompile).toHaveBeenCalled();
expect(mockCompile.calls.mostRecent().args[0].indexOf("mct-include")) expect(mockCompile.mostRecentCall.args[0].indexOf("mct-include"))
.not.toEqual(-1); .not.toEqual(-1);
}); });

View File

@@ -39,6 +39,7 @@ define([
"./src/policies/EditableMovePolicy", "./src/policies/EditableMovePolicy",
"./src/policies/EditContextualActionPolicy", "./src/policies/EditContextualActionPolicy",
"./src/representers/EditRepresenter", "./src/representers/EditRepresenter",
"./src/representers/EditToolbarRepresenter",
"./src/capabilities/EditorCapability", "./src/capabilities/EditorCapability",
"./src/capabilities/TransactionCapabilityDecorator", "./src/capabilities/TransactionCapabilityDecorator",
"./src/services/TransactionManager", "./src/services/TransactionManager",
@@ -77,6 +78,7 @@ define([
EditableMovePolicy, EditableMovePolicy,
EditContextualActionPolicy, EditContextualActionPolicy,
EditRepresenter, EditRepresenter,
EditToolbarRepresenter,
EditorCapability, EditorCapability,
TransactionCapabilityDecorator, TransactionCapabilityDecorator,
TransactionManager, TransactionManager,
@@ -379,6 +381,12 @@ define([
"depends": [ "depends": [
"$log" "$log"
] ]
},
{
"implementation": EditToolbarRepresenter,
"depends": [
"openmct"
]
} }
], ],
"constants": [ "constants": [
@@ -416,17 +424,6 @@ define([
"transactionService" "transactionService"
] ]
} }
],
"runs": [
{
depends: [
"toolbars[]",
"openmct"
],
implementation: function (toolbars, openmct) {
toolbars.forEach(openmct.toolbars.addProvider, openmct.toolbars);
}
}
] ]
} }
}); });

View File

@@ -24,8 +24,7 @@
<div class="items-select left flex-elem l-flex-row grows"> <div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'" <mct-representation key="'back-arrow'"
mct-object="domainObject" mct-object="domainObject"
class="flex-elem l-back"> class="flex-elem l-back"></mct-representation>
</mct-representation>
<mct-representation key="'object-header'" <mct-representation key="'object-header'"
mct-object="domainObject" mct-object="domainObject"
class="l-flex-row flex-elem grows object-header"> class="l-flex-row flex-elem grows object-header">
@@ -49,8 +48,8 @@
<!-- Toolbar and Save/Cancel buttons --> <!-- Toolbar and Save/Cancel buttons -->
<div class="l-edit-controls flex-elem l-flex-row flex-align-end"> <div class="l-edit-controls flex-elem l-flex-row flex-align-end">
<mct-toolbar name="mctToolbar" <mct-toolbar name="mctToolbar"
structure="editToolbar.structure" structure="toolbar.structure"
ng-model="editToolbar.state" ng-model="toolbar.state"
class="flex-elem grows"> class="flex-elem grows">
</mct-toolbar> </mct-toolbar>
<mct-representation key="'edit-action-buttons'" <mct-representation key="'edit-action-buttons'"
@@ -62,6 +61,7 @@
<mct-representation key="representation.selected.key" <mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject" mct-object="representation.selected.key && domainObject"
class="abs flex-elem grows object-holder-main scroll" class="abs flex-elem grows object-holder-main scroll"
toolbar="toolbar"
mct-selectable="{ mct-selectable="{
item: domainObject.useCapability('adapter'), item: domainObject.useCapability('adapter'),
oldItem: domainObject oldItem: domainObject

View File

@@ -24,7 +24,7 @@
class="flex-elem holder" class="flex-elem holder"
ng-model="filterBy"> ng-model="filterBy">
</mct-include> </mct-include>
<div class="flex-elem grows vscroll scroll-pad"> <div class="flex-elem grows vscroll">
<ul class="tree" id="inspector-elements-tree" <ul class="tree" id="inspector-elements-tree"
ng-if="composition.length > 0"> ng-if="composition.length > 0">
<li ng-repeat="containedObject in composition | filter:searchElements"> <li ng-repeat="containedObject in composition | filter:searchElements">

View File

@@ -20,110 +20,192 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
define( define(
[ [],
'../../../../../src/api/objects/object-utils', function () {
'lodash'
], // Utility functions for reducing truth arrays
function ( function and(a, b) {
objectUtils, return a && b;
_ }
) { function or(a, b) {
return a || b;
}
/** /**
* Provides initial structure and state (as suitable for provision * Provides initial structure and state (as suitable for provision
* to the `mct-toolbar` directive) for a view's toolbar, based on * to the `mct-toolbar` directive) for a view's tool bar, based on
* that view's declaration of what belongs in its toolbar and on * that view's declaration of what belongs in its tool bar and on
* the current selection. * the current selection.
* *
* @param $scope the Angular scope * @param structure toolbar structure, as provided by view definition
* @param {Object} openmct the openmct object * @param {Function} commit callback to invoke after changes
* @param structure the toolbar structure
* @memberof platform/commonUI/edit * @memberof platform/commonUI/edit
* @constructor * @constructor
*/ */
function EditToolbar($scope, openmct, structure) { function EditToolbar(structure, commit) {
this.toolbarStructure = [];
this.properties = [];
this.toolbarState = [];
this.openmct = openmct;
this.domainObjectsById = {};
this.unobserveObjects = [];
this.stateTracker = [];
$scope.$watchCollection(this.getState.bind(this), this.handleStateChanges.bind(this));
$scope.$on("$destroy", this.destroy.bind(this));
this.updateToolbar(structure);
this.registerListeners(structure);
}
/**
* Updates the toolbar with a new structure.
*
* @param {Array} structure the toolbar structure
*/
EditToolbar.prototype.updateToolbar = function (structure) {
var self = this; var self = this;
function addKey(item) { // Generate a new key for an item's property
self.stateTracker.push({ function addKey(property) {
id: objectUtils.makeKeyString(item.domainObject.identifier), self.properties.push(property);
domainObject: item.domainObject,
property: item.property
});
self.properties.push(item.property);
return self.properties.length - 1; // Return index of property return self.properties.length - 1; // Return index of property
} }
// Invoke all functions in selections with the given name
function invoke(method, value) {
if (method) {
// Make the change in the selection
self.selection.forEach(function (selected) {
if (typeof selected[method] === 'function') {
selected[method](value);
}
});
// ...and commit!
commit();
}
}
// Prepare a toolbar item based on current selection
function convertItem(item) { function convertItem(item) {
var converted = Object.create(item || {}); var converted = Object.create(item || {});
if (item.property) { if (item.property) {
converted.key = addKey(item); converted.key = addKey(item.property);
} }
if (item.method) { if (item.method) {
converted.click = function (value) { converted.click = function (v) {
item.method(value); invoke(item.method, v);
}; };
} }
return converted; return converted;
} }
// Prepare a toolbar section
function convertSection(section) {
var converted = Object.create(section || {});
converted.items =
((section || {}).items || [])
.map(convertItem);
return converted;
}
this.toolbarState = [];
this.selection = undefined;
this.properties = [];
this.toolbarStructure = Object.create(structure || {});
this.toolbarStructure.sections =
((structure || {}).sections || []).map(convertSection);
}
// Check if all elements of the selection which have this
// property have the same value for this property.
EditToolbar.prototype.isConsistent = function (property) {
var self = this,
consistent = true,
observed = false,
state;
// Check if a given element of the selection is consistent
// with previously-observed elements for this property.
function checkConsistency(selected) {
var next;
// Ignore selections which don't have this property
if (selected[property] !== undefined) {
// Look up state of this element in the selection
next = self.lookupState(property, selected);
// Detect inconsistency
if (observed) {
consistent = consistent && (next === state);
}
// Track state for next iteration
state = next;
observed = true;
}
}
// Iterate through selections
self.selection.forEach(checkConsistency);
return consistent;
};
// Used to filter out items which are applicable (or not)
// to the current selection.
EditToolbar.prototype.isApplicable = function (item) {
var property = (item || {}).property,
method = (item || {}).method,
exclusive = !!(item || {}).exclusive;
// Check if a selected item defines this property
function hasProperty(selected) {
return (property && (selected[property] !== undefined)) ||
(method && (typeof selected[method] === 'function'));
}
return this.selection.map(hasProperty).reduce(
exclusive ? and : or,
exclusive
) && this.isConsistent(property);
};
// Look up the current value associated with a property
EditToolbar.prototype.lookupState = function (property, selected) {
var value = selected[property];
return (typeof value === 'function') ? value() : value;
};
/**
* Set the current selection. Visibility of sections
* and items in the toolbar will be updated to match this.
* @param {Array} s the new selection
*/
EditToolbar.prototype.setSelection = function (s) {
var self = this;
// Show/hide controls in this section per applicability
function refreshSectionApplicability(section) {
var count = 0;
// Show/hide each item
(section.items || []).forEach(function (item) {
item.hidden = !self.isApplicable(item);
count += item.hidden ? 0 : 1;
});
// Hide this section if there are no applicable items
section.hidden = !count;
}
// Get initial value for a given property // Get initial value for a given property
function initializeState(property) { function initializeState(property) {
var result; var result;
structure.forEach(function (item) { // Look through all selections for this property;
if (item.property === property) { // values should all match by the time we perform
result = _.get(item.domainObject, item.property); // this lookup anyway.
} self.selection.forEach(function (selected) {
result = (selected[property] !== undefined) ?
self.lookupState(property, selected) :
result;
}); });
return result; return result;
} }
// Tracks the domain object and property for every element in the state array this.selection = s;
this.stateTracker = []; this.toolbarStructure.sections.forEach(refreshSectionApplicability);
this.toolbarStructure = structure.map(convertItem);
this.toolbarState = this.properties.map(initializeState); this.toolbarState = this.properties.map(initializeState);
}; };
/** /**
* Gets the structure of the toolbar, as appropriate to * Get the structure of the toolbar, as appropriate to
* pass to `mct-toolbar`. * pass to `mct-toolbar`.
* * @returns the toolbar structure
* @returns {Array} the toolbar structure
*/ */
EditToolbar.prototype.getStructure = function () { EditToolbar.prototype.getStructure = function () {
return this.toolbarStructure; return this.toolbarStructure;
}; };
/** /**
* Gets the current state of the toolbar, as appropriate * Get the current state of the toolbar, as appropriate
* to two-way bind to the state handled by `mct-toolbar`. * to two-way bind to the state handled by `mct-toolbar`.
*
* @returns {Array} state of the toolbar * @returns {Array} state of the toolbar
*/ */
EditToolbar.prototype.getState = function () { EditToolbar.prototype.getState = function () {
@@ -131,124 +213,48 @@ define(
}; };
/** /**
* Mutates the domain object's property with a new value. * Update state within the current selection.
*
* @param {Object} dominObject the domain object
* @param {string} property the domain object's property to update
* @param value the property's new value
*/
EditToolbar.prototype.updateDomainObject = function (domainObject, property, value) {
this.openmct.objects.mutate(domainObject, property, value);
};
/**
* Updates state with the new value.
*
* @param {number} index the index of the corresponding * @param {number} index the index of the corresponding
* element in the state array * element in the state array
* @param value the new value to update the state array with * @param value the new value to convey to the selection
*/ */
EditToolbar.prototype.updateState = function (index, value) { EditToolbar.prototype.updateState = function (index, value) {
this.toolbarState[index] = value;
};
/**
* Register listeners for domain objects to watch for updates.
*
* @param {Array} the toolbar structure
*/
EditToolbar.prototype.registerListeners = function (structure) {
var self = this; var self = this;
function observeObject(domainObject, id) { // Update value for this property in all elements of the
var unobserveObject = self.openmct.objects.observe(domainObject, '*', function (newObject) { // selection which have this property.
self.domainObjectsById[id].newObject = JSON.parse(JSON.stringify(newObject)); function updateProperties(property, val) {
self.scheduleStateUpdate(); var changed = false;
});
self.unobserveObjects.push(unobserveObject); // Update property in a selected element
function updateProperty(selected) {
// Ignore selected elements which don't have this property
if (selected[property] !== undefined) {
// Check if this is a setter, or just assignable
if (typeof selected[property] === 'function') {
changed =
changed || (selected[property]() !== val);
selected[property](val);
} else {
changed =
changed || (selected[property] !== val);
selected[property] = val;
}
}
}
// Update property in all selected elements
self.selection.forEach(updateProperty);
// Return whether or not anything changed
return changed;
} }
structure.forEach(function (item) { return updateProperties(this.properties[index], value);
var domainObject = item.domainObject;
var id = objectUtils.makeKeyString(domainObject.identifier);
if (!self.domainObjectsById[id]) {
self.domainObjectsById[id] = {
domainObject: domainObject,
properties: []
};
observeObject(domainObject, id);
}
self.domainObjectsById[id].properties.push(item.property);
});
};
/**
* Delays updating the state.
*/
EditToolbar.prototype.scheduleStateUpdate = function () {
if (this.stateUpdateScheduled) {
return;
}
this.stateUpdateScheduled = true;
setTimeout(this.updateStateAfterMutation.bind(this));
};
EditToolbar.prototype.updateStateAfterMutation = function () {
this.stateTracker.forEach(function (state, index) {
if (!this.domainObjectsById[state.id].newObject) {
return;
}
var domainObject = this.domainObjectsById[state.id].domainObject;
var newObject = this.domainObjectsById[state.id].newObject;
var currentValue = _.get(domainObject, state.property);
var newValue = _.get(newObject, state.property);
state.domainObject = newObject;
if (currentValue !== newValue) {
this.updateState(index, newValue);
}
}, this);
Object.values(this.domainObjectsById).forEach(function (tracker) {
if (tracker.newObject) {
tracker.domainObject = tracker.newObject;
}
delete tracker.newObject;
});
this.stateUpdateScheduled = false;
};
/**
* Removes the listeners.
*/
EditToolbar.prototype.deregisterListeners = function () {
this.unobserveObjects.forEach(function (unobserveObject) {
unobserveObject();
});
this.unobserveObjects = [];
};
EditToolbar.prototype.handleStateChanges = function (state) {
(state || []).map(function (newValue, index) {
var domainObject = this.stateTracker[index].domainObject;
var property = this.stateTracker[index].property;
var currentValue = _.get(domainObject, property);
if (currentValue !== newValue) {
this.updateDomainObject(domainObject, property, newValue);
}
}, this);
};
EditToolbar.prototype.destroy = function () {
this.deregisterListeners();
}; };
return EditToolbar; return EditToolbar;
} }
); );

View File

@@ -0,0 +1,154 @@
/*****************************************************************************
* 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(
['./EditToolbar', './EditToolbarSelection'],
function (EditToolbar, EditToolbarSelection) {
// No operation
var NOOP_REPRESENTER = {
represent: function () {},
destroy: function () {}
};
/**
* The EditToolbarRepresenter populates the toolbar in Edit mode
* based on a view's definition.
* @param {Scope} scope the Angular scope of the representation
* @memberof platform/commonUI/edit
* @constructor
* @implements {Representer}
*/
function EditToolbarRepresenter(openmct, scope, element, attrs) {
var self = this;
// Mark changes as ready to persist
function commit(message) {
if (scope.commit) {
scope.commit(message);
}
}
// Handle changes to the current selection
function updateSelection(selection) {
// Only update if there is a toolbar to update
if (self.toolbar) {
// Make sure selection is array-like
selection = Array.isArray(selection) ?
selection :
(selection ? [selection] : []);
// Update the toolbar's selection
self.toolbar.setSelection(selection);
// ...and expose its structure/state
self.toolbarObject.structure =
self.toolbar.getStructure();
self.toolbarObject.state =
self.toolbar.getState();
}
}
// Get state (to watch it)
function getState() {
return self.toolbarObject.state;
}
// Update selection models to match changed toolbar state
function updateState(state) {
// Update underlying state based on toolbar changes
var changed = (state || []).map(function (value, index) {
return self.toolbar.updateState(index, value);
}).reduce(function (a, b) {
return a || b;
}, false);
// Only commit if something actually changed
if (changed) {
// Commit the changes.
commit("Changes from toolbar.");
}
}
this.clearExposedToolbar = function () {
// Clear exposed toolbar state (if any)
if (attrs.toolbar) {
delete scope.$parent[attrs.toolbar];
}
};
this.exposeToolbar = function () {
scope.$parent[self.attrs.toolbar] = self.toolbarObject;
};
this.commit = commit;
this.attrs = attrs;
this.updateSelection = updateSelection;
this.toolbar = undefined;
this.toolbarObject = {};
this.openmct = openmct;
this.scope = scope;
// If this representation exposes a toolbar, set up watches
// to synchronize with it.
if (attrs && attrs.toolbar) {
// Detect and handle changes to state from the toolbar
scope.$watchCollection(getState, updateState);
// Watch for changes in the current selection state
scope.$watchCollection("selection.all()", updateSelection);
// Expose toolbar state under that name
scope.$parent[attrs.toolbar] = this.toolbarObject;
} else {
// No toolbar declared, so do nothing.
return NOOP_REPRESENTER;
}
}
// Represent a domain object using this definition
EditToolbarRepresenter.prototype.represent = function (representation) {
// Get the newest toolbar definition from the view
var definition = (representation || {}).toolbar || {};
// If we have been asked to expose toolbar state...
if (this.attrs.toolbar) {
// Initialize toolbar object
this.toolbar = new EditToolbar(definition, this.commit);
// Ensure toolbar state is exposed
this.exposeToolbar();
}
// Add toolbar selection to scope.
this.scope.selection = new EditToolbarSelection(
this.scope,
this.openmct
);
// Initialize toolbar to current selection
this.updateSelection(this.scope.selection.all());
};
// Destroy; remove toolbar object from parent scope
EditToolbarRepresenter.prototype.destroy = function () {
this.clearExposedToolbar();
};
return EditToolbarRepresenter;
}
);

View File

@@ -0,0 +1,157 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Tracks selection state for editable views. Selection is
* implemented such that (from the toolbar's perspective)
* up to two objects can be "selected" at any given time:
*
* * The view proxy (see the `proxy` method), which provides
* an interface for interacting with the view itself (e.g.
* for buttons like "Add")
* * The selection, for single selected elements within the
* view.
*
* @memberof platform/commonUI/edit
* @constructor
*/
function EditToolbarSelection($scope, openmct) {
this.selection = [{}];
this.selecting = false;
this.selectedObj = undefined;
this.openmct = openmct;
var self = this;
function setSelection(selection) {
var selected = selection[0];
if (selected && selected.context.toolbar) {
self.select(selected.context.toolbar);
} else {
self.deselect();
}
if (selected && selected.context.viewProxy) {
self.proxy(selected.context.viewProxy);
}
setTimeout(function () {
$scope.$apply();
});
}
$scope.$on("$destroy", function () {
self.openmct.selection.off('change', setSelection);
});
this.openmct.selection.on('change', setSelection);
setSelection(this.openmct.selection.get());
}
/**
* Check if an object is currently selected.
* @param {*} obj the object to check for selection
* @returns {boolean} true if selected, otherwise false
*/
EditToolbarSelection.prototype.selected = function (obj) {
return (obj === this.selectedObj) || (obj === this.selection[0]);
};
/**
* Select an object.
* @param obj the object to select
* @returns {boolean} true if selection changed
*/
EditToolbarSelection.prototype.select = function (obj) {
// Proxy is always selected
if (obj === this.selection[0]) {
return false;
}
// Clear any existing selection
this.deselect();
// Note the current selection state
this.selectedObj = obj;
this.selecting = true;
// Add the selection
this.selection.push(obj);
};
/**
* Clear the current selection.
* @returns {boolean} true if selection changed
*/
EditToolbarSelection.prototype.deselect = function () {
// Nothing to do if we don't have a selected object
if (this.selecting) {
// Clear state tracking
this.selecting = false;
this.selectedObj = undefined;
// Remove the selection
this.selection.pop();
return true;
}
return false;
};
/**
* Get the currently-selected object.
* @returns the currently selected object
*/
EditToolbarSelection.prototype.get = function () {
return this.selectedObj;
};
/**
* Get/set the view proxy (for toolbar actions taken upon
* the view itself.)
* @param [proxy] the view proxy (if setting)
* @returns the current view proxy
*/
EditToolbarSelection.prototype.proxy = function (p) {
if (arguments.length > 0) {
this.selection[0] = p;
}
return this.selection[0];
};
/**
* Get an array containing all selections, including the
* selection proxy. It is generally not advisable to
* mutate this array directly.
* @returns {Array} all selections
*/
EditToolbarSelection.prototype.all = function () {
return this.selection;
};
return EditToolbarSelection;
}
);

View File

@@ -49,7 +49,7 @@ define(
"getModel" "getModel"
] ]
); );
mockDomainObject.getModel.and.returnValue({}); mockDomainObject.getModel.andReturn({});
mockParentObject = jasmine.createSpyObj( mockParentObject = jasmine.createSpyObj(
"parentObject", "parentObject",
@@ -57,7 +57,7 @@ define(
"getCapability" "getCapability"
] ]
); );
mockParentObject.getCapability.and.callFake(function (name) { mockParentObject.getCapability.andCallFake(function (name) {
return parentCapabilities[name]; return parentCapabilities[name];
}); });
@@ -77,14 +77,14 @@ define(
"getOriginal" "getOriginal"
] ]
); );
capabilities.location.getOriginal.and.returnValue(mockPromise(mockDomainObject)); capabilities.location.getOriginal.andReturn(mockPromise(mockDomainObject));
capabilities.context = jasmine.createSpyObj( capabilities.context = jasmine.createSpyObj(
"contextCapability", "contextCapability",
[ [
"getParent" "getParent"
] ]
); );
capabilities.context.getParent.and.returnValue(mockParentObject); capabilities.context.getParent.andReturn(mockParentObject);
parentCapabilities.action = jasmine.createSpyObj( parentCapabilities.action = jasmine.createSpyObj(
"actionCapability", "actionCapability",
@@ -97,37 +97,37 @@ define(
domainObject: mockDomainObject domainObject: mockDomainObject
}; };
mockDomainObject.getCapability.and.callFake(function (name) { mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name]; return capabilities[name];
}); });
mockDomainObject.hasCapability.and.callFake(function (name) { mockDomainObject.hasCapability.andCallFake(function (name) {
return !!capabilities[name]; return !!capabilities[name];
}); });
capabilities.editor.finish.and.returnValue(mockPromise(true)); capabilities.editor.finish.andReturn(mockPromise(true));
action = new CancelAction(actionContext); action = new CancelAction(actionContext);
}); });
it("only applies to domain object that is being edited", function () { it("only applies to domain object that is being edited", function () {
capabilities.editor.isEditContextRoot.and.returnValue(true); capabilities.editor.isEditContextRoot.andReturn(true);
expect(CancelAction.appliesTo(actionContext)).toBeTruthy(); expect(CancelAction.appliesTo(actionContext)).toBeTruthy();
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
capabilities.editor.isEditContextRoot.and.returnValue(false); capabilities.editor.isEditContextRoot.andReturn(false);
expect(CancelAction.appliesTo(actionContext)).toBeFalsy(); expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
mockDomainObject.hasCapability.and.returnValue(false); mockDomainObject.hasCapability.andReturn(false);
expect(CancelAction.appliesTo(actionContext)).toBeFalsy(); expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
}); });
it("invokes the editor capability's cancel functionality when" + it("invokes the editor capability's cancel functionality when" +
" performed", function () { " performed", function () {
mockDomainObject.getModel.and.returnValue({persisted: 1}); mockDomainObject.getModel.andReturn({persisted: 1});
//Return true from navigate action //Return true from navigate action
capabilities.action.perform.and.returnValue(mockPromise(true)); capabilities.action.perform.andReturn(mockPromise(true));
action.perform(); action.perform();
// Should have called finish // Should have called finish
@@ -138,15 +138,15 @@ define(
}); });
it("navigates to object if existing using navigate action", function () { it("navigates to object if existing using navigate action", function () {
mockDomainObject.getModel.and.returnValue({persisted: 1}); mockDomainObject.getModel.andReturn({persisted: 1});
//Return true from navigate action //Return true from navigate action
capabilities.action.perform.and.returnValue(mockPromise(true)); capabilities.action.perform.andReturn(mockPromise(true));
action.perform(); action.perform();
expect(capabilities.action.perform).toHaveBeenCalledWith("navigate"); expect(capabilities.action.perform).toHaveBeenCalledWith("navigate");
}); });
it("navigates to parent if new using navigate action", function () { it("navigates to parent if new using navigate action", function () {
mockDomainObject.getModel.and.returnValue({persisted: undefined}); mockDomainObject.getModel.andReturn({persisted: undefined});
action.perform(); action.perform();
expect(parentCapabilities.action.perform).toHaveBeenCalledWith("navigate"); expect(parentCapabilities.action.perform).toHaveBeenCalledWith("navigate");
}); });

View File

@@ -66,11 +66,11 @@ define(
editor: mockEditor editor: mockEditor
}; };
mockDomainObject.getCapability.and.callFake(function (name) { mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name]; return capabilities[name];
}); });
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
actionContext = { domainObject: mockDomainObject }; actionContext = { domainObject: mockDomainObject };
@@ -92,9 +92,9 @@ define(
}); });
it("is only applicable to objects not already in edit mode", function () { it("is only applicable to objects not already in edit mode", function () {
mockEditor.isEditContextRoot.and.returnValue(false); mockEditor.isEditContextRoot.andReturn(false);
expect(EditAction.appliesTo(actionContext)).toBe(true); expect(EditAction.appliesTo(actionContext)).toBe(true);
mockEditor.isEditContextRoot.and.returnValue(true); mockEditor.isEditContextRoot.andReturn(true);
expect(EditAction.appliesTo(actionContext)).toBe(false); expect(EditAction.appliesTo(actionContext)).toBe(false);
}); });

View File

@@ -71,14 +71,14 @@ define(
mockActionCapability = jasmine.createSpyObj("actionCapability", ["getActions"]); mockActionCapability = jasmine.createSpyObj("actionCapability", ["getActions"]);
mockEditAction = jasmine.createSpyObj("editAction", ["perform"]); mockEditAction = jasmine.createSpyObj("editAction", ["perform"]);
mockDomainObject.getId.and.returnValue("test"); mockDomainObject.getId.andReturn("test");
mockDomainObject.getCapability.and.returnValue(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockContext.getParent.and.returnValue(mockParent); mockContext.getParent.andReturn(mockParent);
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
mockType.getKey.and.returnValue("layout"); mockType.getKey.andReturn("layout");
mockComposition.invoke.and.returnValue(mockPromise(true)); mockComposition.invoke.andReturn(mockPromise(true));
mockComposition.add.and.returnValue(mockPromise(true)); mockComposition.add.andReturn(mockPromise(true));
mockActionCapability.getActions.and.returnValue([]); mockActionCapability.getActions.andReturn([]);
capabilities = { capabilities = {
composition: mockComposition, composition: mockComposition,
@@ -105,14 +105,14 @@ define(
}); });
it("enables edit mode for objects that have an edit action", function () { it("enables edit mode for objects that have an edit action", function () {
mockActionCapability.getActions.and.returnValue([mockEditAction]); mockActionCapability.getActions.andReturn([mockEditAction]);
action.perform(); action.perform();
expect(mockEditAction.perform).toHaveBeenCalled(); expect(mockEditAction.perform).toHaveBeenCalled();
}); });
it("Does not enable edit mode for objects that do not have an" + it("Does not enable edit mode for objects that do not have an" +
" edit action", function () { " edit action", function () {
mockActionCapability.getActions.and.returnValue([]); mockActionCapability.getActions.andReturn([]);
action.perform(); action.perform();
expect(mockEditAction.perform).not.toHaveBeenCalled(); expect(mockEditAction.perform).not.toHaveBeenCalled();
expect(mockComposition.add) expect(mockComposition.add)

View File

@@ -71,8 +71,8 @@ define(
} }
}; };
capabilities.type.hasFeature.and.returnValue(true); capabilities.type.hasFeature.andReturn(true);
capabilities.mutation.and.returnValue(true); capabilities.mutation.andReturn(true);
action = new PropertiesAction(dialogService, context); action = new PropertiesAction(dialogService, context);
}); });
@@ -80,7 +80,7 @@ define(
it("mutates an object when performed", function () { it("mutates an object when performed", function () {
action.perform(); action.perform();
expect(capabilities.mutation).toHaveBeenCalled(); expect(capabilities.mutation).toHaveBeenCalled();
capabilities.mutation.calls.mostRecent().args[0]({}); capabilities.mutation.mostRecentCall.args[0]({});
}); });
it("does not muate object upon cancel", function () { it("does not muate object upon cancel", function () {

View File

@@ -95,13 +95,13 @@ define(
"removeListener" "removeListener"
] ]
); );
mockNavigationService.getNavigation.and.returnValue(mockDomainObject); mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockDomainObject.getId.and.returnValue("test"); mockDomainObject.getId.andReturn("test");
mockDomainObject.getCapability.and.returnValue(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockContext.getParent.and.returnValue(mockParent); mockContext.getParent.andReturn(mockParent);
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
capabilities = { capabilities = {
mutation: mockMutation, mutation: mockMutation,
@@ -119,7 +119,7 @@ define(
it("only applies to objects with parents", function () { it("only applies to objects with parents", function () {
expect(RemoveAction.appliesTo(actionContext)).toBeTruthy(); expect(RemoveAction.appliesTo(actionContext)).toBeTruthy();
mockContext.getParent.and.returnValue(undefined); mockContext.getParent.andReturn(undefined);
expect(RemoveAction.appliesTo(actionContext)).toBeFalsy(); expect(RemoveAction.appliesTo(actionContext)).toBeFalsy();
@@ -136,7 +136,7 @@ define(
it("changes composition from its mutation function", function () { it("changes composition from its mutation function", function () {
var mutator, result; var mutator, result;
action.perform(); action.perform();
mutator = mockMutation.invoke.calls.mostRecent().args[0]; mutator = mockMutation.invoke.mostRecentCall.args[0];
result = mutator(model); result = mutator(model);
// Should not have cancelled the mutation // Should not have cancelled the mutation
@@ -153,22 +153,22 @@ define(
it("removes parent of object currently navigated to", function () { it("removes parent of object currently navigated to", function () {
// Navigates to child object // Navigates to child object
mockNavigationService.getNavigation.and.returnValue(mockChildObject); mockNavigationService.getNavigation.andReturn(mockChildObject);
// Test is id of object being removed // Test is id of object being removed
// Child object has different id // Child object has different id
mockDomainObject.getId.and.returnValue("test"); mockDomainObject.getId.andReturn("test");
mockChildObject.getId.and.returnValue("not test"); mockChildObject.getId.andReturn("not test");
// Sets context for the child and domainObject // Sets context for the child and domainObject
mockDomainObject.getCapability.and.returnValue(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockChildObject.getCapability.and.returnValue(mockChildContext); mockChildObject.getCapability.andReturn(mockChildContext);
// Parents of child and domainObject are set // Parents of child and domainObject are set
mockContext.getParent.and.returnValue(mockParent); mockContext.getParent.andReturn(mockParent);
mockChildContext.getParent.and.returnValue(mockDomainObject); mockChildContext.getParent.andReturn(mockDomainObject);
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
action.perform(); action.perform();
@@ -178,25 +178,25 @@ define(
it("checks if removing object not in ascendent path (reaches ROOT)", function () { it("checks if removing object not in ascendent path (reaches ROOT)", function () {
// Navigates to grandchild of ROOT // Navigates to grandchild of ROOT
mockNavigationService.getNavigation.and.returnValue(mockGrandchildObject); mockNavigationService.getNavigation.andReturn(mockGrandchildObject);
// domainObject (grandparent) is set as ROOT, child and grandchild // domainObject (grandparent) is set as ROOT, child and grandchild
// are set objects not being removed // are set objects not being removed
mockDomainObject.getId.and.returnValue("test 1"); mockDomainObject.getId.andReturn("test 1");
mockRootObject.getId.and.returnValue("ROOT"); mockRootObject.getId.andReturn("ROOT");
mockChildObject.getId.and.returnValue("not test 2"); mockChildObject.getId.andReturn("not test 2");
mockGrandchildObject.getId.and.returnValue("not test 3"); mockGrandchildObject.getId.andReturn("not test 3");
// Sets context for the grandchild, child, and domainObject // Sets context for the grandchild, child, and domainObject
mockRootObject.getCapability.and.returnValue(mockRootContext); mockRootObject.getCapability.andReturn(mockRootContext);
mockChildObject.getCapability.and.returnValue(mockChildContext); mockChildObject.getCapability.andReturn(mockChildContext);
mockGrandchildObject.getCapability.and.returnValue(mockGrandchildContext); mockGrandchildObject.getCapability.andReturn(mockGrandchildContext);
// Parents of grandchild and child are set // Parents of grandchild and child are set
mockChildContext.getParent.and.returnValue(mockRootObject); mockChildContext.getParent.andReturn(mockRootObject);
mockGrandchildContext.getParent.and.returnValue(mockChildObject); mockGrandchildContext.getParent.andReturn(mockChildObject);
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
action.perform(); action.perform();

View File

@@ -19,7 +19,7 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/ /*global describe,it,expect,beforeEach,jasmine,waitsFor,runs*/
define( define(
["../../src/actions/SaveAction"], ["../../src/actions/SaveAction"],
@@ -81,13 +81,13 @@ define(
["info", "error"] ["info", "error"]
); );
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.and.callFake(function (capability) { mockDomainObject.getCapability.andCallFake(function (capability) {
return capabilities[capability]; return capabilities[capability];
}); });
mockDomainObject.getModel.and.returnValue({persisted: 0}); mockDomainObject.getModel.andReturn({persisted: 0});
mockEditorCapability.save.and.returnValue(mockPromise(true)); mockEditorCapability.save.andReturn(mockPromise(true));
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
action = new SaveAction(mockDialogService, mockNotificationService, actionContext); action = new SaveAction(mockDialogService, mockNotificationService, actionContext);
}); });
@@ -96,14 +96,14 @@ define(
expect(SaveAction.appliesTo(actionContext)).toBe(true); expect(SaveAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.hasCapability.and.returnValue(false); mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.and.returnValue(undefined); mockDomainObject.getCapability.andReturn(undefined);
expect(SaveAction.appliesTo(actionContext)).toBe(false); expect(SaveAction.appliesTo(actionContext)).toBe(false);
}); });
it("only applies to domain object that has already been persisted", it("only applies to domain object that has already been persisted",
function () { function () {
mockDomainObject.getModel.and.returnValue({persisted: undefined}); mockDomainObject.getModel.andReturn({persisted: undefined});
expect(SaveAction.appliesTo(actionContext)).toBe(false); expect(SaveAction.appliesTo(actionContext)).toBe(false);
}); });
@@ -118,11 +118,11 @@ define(
beforeEach(function () { beforeEach(function () {
mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]); mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]);
mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle); mockDialogService.showBlockingMessage.andReturn(mockDialogHandle);
}); });
it("shows a dialog while saving", function () { it("shows a dialog while saving", function () {
mockEditorCapability.save.and.returnValue(new Promise(function () { mockEditorCapability.save.andReturn(new Promise(function () {
})); }));
action.perform(); action.perform();
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled(); expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
@@ -137,8 +137,12 @@ define(
it("notifies if saving succeeded", function () { it("notifies if saving succeeded", function () {
var mockCallback = jasmine.createSpy("callback"); var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.resolve()); mockEditorCapability.save.andReturn(Promise.resolve("success"));
return action.perform().then(mockCallback).then(function () { action.perform().then(mockCallback);
waitsFor(function () {
return mockCallback.calls.length > 0;
});
runs(function () {
expect(mockNotificationService.info).toHaveBeenCalled(); expect(mockNotificationService.info).toHaveBeenCalled();
expect(mockNotificationService.error).not.toHaveBeenCalled(); expect(mockNotificationService.error).not.toHaveBeenCalled();
}); });
@@ -146,8 +150,12 @@ define(
it("notifies if saving failed", function () { it("notifies if saving failed", function () {
var mockCallback = jasmine.createSpy("callback"); var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.reject("some failure reason")); mockEditorCapability.save.andReturn(Promise.reject("some failure reason"));
return action.perform().then(mockCallback).then(function () { action.perform().then(mockCallback);
waitsFor(function () {
return mockCallback.calls.length > 0;
});
runs(function () {
expect(mockNotificationService.error).toHaveBeenCalled(); expect(mockNotificationService.error).toHaveBeenCalled();
expect(mockNotificationService.info).not.toHaveBeenCalled(); expect(mockNotificationService.info).not.toHaveBeenCalled();
}); });

View File

@@ -86,13 +86,13 @@ define(
["info", "error"] ["info", "error"]
); );
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.and.callFake(function (capability) { mockDomainObject.getCapability.andCallFake(function (capability) {
return capabilities[capability]; return capabilities[capability];
}); });
mockDomainObject.getModel.and.returnValue({ persisted: 0 }); mockDomainObject.getModel.andReturn({ persisted: 0 });
mockEditorCapability.save.and.returnValue(mockPromise(true)); mockEditorCapability.save.andReturn(mockPromise(true));
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext); action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext);
}); });
@@ -102,18 +102,18 @@ define(
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true); expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.hasCapability.and.returnValue(false); mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.and.returnValue(undefined); mockDomainObject.getCapability.andReturn(undefined);
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false); expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false);
}); });
it("only applies to domain object that has already been persisted", function () { it("only applies to domain object that has already been persisted", function () {
mockDomainObject.getModel.and.returnValue({ persisted: undefined }); mockDomainObject.getModel.andReturn({ persisted: undefined });
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false); expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(false);
}); });
it("does not close the editor before completing the save", function () { it("does not close the editor before completing the save", function () {
mockEditorCapability.save.and.returnValue(new Promise(function () { mockEditorCapability.save.andReturn(new Promise(function () {
})); }));
action.perform(); action.perform();
expect(mockEditorCapability.save).toHaveBeenCalled(); expect(mockEditorCapability.save).toHaveBeenCalled();

View File

@@ -19,7 +19,7 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine,spyOn*/ /*global describe,it,expect,beforeEach,jasmine,runs,waitsFor,spyOn*/
define( define(
["../../src/actions/SaveAsAction"], ["../../src/actions/SaveAsAction"],
@@ -63,12 +63,12 @@ define(
"getId" "getId"
] ]
); );
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.and.callFake(function (capability) { mockDomainObject.getCapability.andCallFake(function (capability) {
return capabilities[capability]; return capabilities[capability];
}); });
mockDomainObject.getModel.and.returnValue({location: 'a', persisted: undefined}); mockDomainObject.getModel.andReturn({location: 'a', persisted: undefined});
mockDomainObject.getId.and.returnValue(0); mockDomainObject.getId.andReturn(0);
mockClonedObject = jasmine.createSpyObj( mockClonedObject = jasmine.createSpyObj(
"clonedObject", "clonedObject",
@@ -76,7 +76,7 @@ define(
"getId" "getId"
] ]
); );
mockClonedObject.getId.and.returnValue(1); mockClonedObject.getId.andReturn(1);
mockParent = jasmine.createSpyObj( mockParent = jasmine.createSpyObj(
"parentObject", "parentObject",
@@ -91,9 +91,9 @@ define(
"editor", "editor",
["save", "finish", "isEditContextRoot"] ["save", "finish", "isEditContextRoot"]
); );
mockEditorCapability.save.and.returnValue(mockPromise(true)); mockEditorCapability.save.andReturn(mockPromise(true));
mockEditorCapability.finish.and.returnValue(mockPromise(true)); mockEditorCapability.finish.andReturn(mockPromise(true));
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
capabilities.editor = mockEditorCapability; capabilities.editor = mockEditorCapability;
mockActionCapability = jasmine.createSpyObj( mockActionCapability = jasmine.createSpyObj(
@@ -106,7 +106,7 @@ define(
"objectService", "objectService",
["getObjects"] ["getObjects"]
); );
mockObjectService.getObjects.and.returnValue(mockPromise({'a': mockParent})); mockObjectService.getObjects.andReturn(mockPromise({'a': mockParent}));
mockDialogService = jasmine.createSpyObj( mockDialogService = jasmine.createSpyObj(
"dialogService", "dialogService",
@@ -115,7 +115,7 @@ define(
"showBlockingMessage" "showBlockingMessage"
] ]
); );
mockDialogService.getUserInput.and.returnValue(mockPromise(undefined)); mockDialogService.getUserInput.andReturn(mockPromise(undefined));
mockCopyService = jasmine.createSpyObj( mockCopyService = jasmine.createSpyObj(
"copyService", "copyService",
@@ -123,7 +123,7 @@ define(
"perform" "perform"
] ]
); );
mockCopyService.perform.and.returnValue(mockPromise(mockClonedObject)); mockCopyService.perform.andReturn(mockPromise(mockClonedObject));
mockNotificationService = jasmine.createSpyObj( mockNotificationService = jasmine.createSpyObj(
"notificationService", "notificationService",
@@ -146,10 +146,10 @@ define(
actionContext); actionContext);
spyOn(action, "getObjectService"); spyOn(action, "getObjectService");
action.getObjectService.and.returnValue(mockObjectService); action.getObjectService.andReturn(mockObjectService);
spyOn(action, "createWizard"); spyOn(action, "createWizard");
action.createWizard.and.returnValue({ action.createWizard.andReturn({
getFormStructure: noop, getFormStructure: noop,
getInitialFormValue: noop, getInitialFormValue: noop,
populateObjectFromInput: function () { populateObjectFromInput: function () {
@@ -163,8 +163,8 @@ define(
expect(SaveAsAction.appliesTo(actionContext)).toBe(true); expect(SaveAsAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.hasCapability.and.returnValue(false); mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.and.returnValue(undefined); mockDomainObject.getCapability.andReturn(undefined);
expect(SaveAsAction.appliesTo(actionContext)).toBe(false); expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
}); });
@@ -173,27 +173,35 @@ define(
expect(SaveAsAction.appliesTo(actionContext)).toBe(true); expect(SaveAsAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
mockDomainObject.getModel.and.returnValue({persisted: 0}); mockDomainObject.getModel.andReturn({persisted: 0});
expect(SaveAsAction.appliesTo(actionContext)).toBe(false); expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
}); });
it("uses the editor capability to save the object", function () { it("uses the editor capability to save the object", function () {
mockEditorCapability.save.and.returnValue(Promise.resolve()); mockEditorCapability.save.andReturn(new Promise(function () {}));
runs(function () {
return action.perform().then(function () { action.perform();
expect(mockEditorCapability.save).toHaveBeenCalled(); });
waitsFor(function () {
return mockEditorCapability.save.calls.length > 0;
}, "perform() should call EditorCapability.save");
runs(function () {
expect(mockEditorCapability.finish).not.toHaveBeenCalled();
}); });
}); });
it("uses the editor capability to finish editing the object", function () { it("uses the editor capability to finish editing the object", function () {
return action.perform().then(function () { runs(function () {
expect(mockEditorCapability.finish.calls.count()).toBeGreaterThan(0); action.perform();
}); });
waitsFor(function () {
return mockEditorCapability.finish.calls.length > 0;
}, "perform() should call EditorCapability.finish");
}); });
it("returns to browse after save", function () { it("returns to browse after save", function () {
spyOn(action, "save"); spyOn(action, "save");
action.save.and.returnValue(mockPromise(mockDomainObject)); action.save.andReturn(mockPromise(mockDomainObject));
action.perform(); action.perform();
expect(mockActionCapability.perform).toHaveBeenCalledWith( expect(mockActionCapability.perform).toHaveBeenCalledWith(
"navigate" "navigate"
@@ -210,33 +218,48 @@ define(
beforeEach(function () { beforeEach(function () {
mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]); mockDialogHandle = jasmine.createSpyObj("dialogHandle", ["dismiss"]);
mockDialogService.showBlockingMessage.and.returnValue(mockDialogHandle); mockDialogService.showBlockingMessage.andReturn(mockDialogHandle);
}); });
it("shows a blocking dialog indicating that saving is in progress", function () { it("shows a blocking dialog indicating that saving is in progress", function () {
mockEditorCapability.save.and.returnValue(new Promise(function () {})); mockEditorCapability.save.andReturn(new Promise(function () {}));
action.perform(); action.perform();
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled(); expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
expect(mockDialogHandle.dismiss).not.toHaveBeenCalled(); expect(mockDialogHandle.dismiss).not.toHaveBeenCalled();
}); });
it("hides the blocking dialog after saving finishes", function () { it("hides the blocking dialog after saving finishes", function () {
return action.perform().then(function () { var mockCallback = jasmine.createSpy();
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled(); action.perform().then(mockCallback);
expect(mockDialogService.showBlockingMessage).toHaveBeenCalled();
waitsFor(function () {
return mockCallback.calls.length > 0;
});
runs(function () {
expect(mockDialogHandle.dismiss).toHaveBeenCalled(); expect(mockDialogHandle.dismiss).toHaveBeenCalled();
}); });
}); });
it("notifies if saving succeeded", function () { it("notifies if saving succeeded", function () {
return action.perform().then(function () { var mockCallback = jasmine.createSpy();
action.perform().then(mockCallback);
waitsFor(function () {
return mockCallback.calls.length > 0;
});
runs(function () {
expect(mockNotificationService.info).toHaveBeenCalled(); expect(mockNotificationService.info).toHaveBeenCalled();
expect(mockNotificationService.error).not.toHaveBeenCalled(); expect(mockNotificationService.error).not.toHaveBeenCalled();
}); });
}); });
it("notifies if saving failed", function () { it("notifies if saving failed", function () {
mockCopyService.perform.and.returnValue(Promise.reject("some failure reason")); mockCopyService.perform.andReturn(Promise.reject("some failure reason"));
action.perform().then(function () { var mockCallback = jasmine.createSpy();
action.perform().then(mockCallback);
waitsFor(function () {
return mockCallback.calls.length > 0;
});
runs(function () {
expect(mockNotificationService.error).toHaveBeenCalled(); expect(mockNotificationService.error).toHaveBeenCalled();
expect(mockNotificationService.info).not.toHaveBeenCalled(); expect(mockNotificationService.info).not.toHaveBeenCalled();
}); });

View File

@@ -60,8 +60,8 @@ define(
"cancel" "cancel"
] ]
); );
mockTransactionService.commit.and.returnValue(fastPromise()); mockTransactionService.commit.andReturn(fastPromise());
mockTransactionService.cancel.and.returnValue(fastPromise()); mockTransactionService.cancel.andReturn(fastPromise());
mockTransactionService.isActive = jasmine.createSpy('isActive'); mockTransactionService.isActive = jasmine.createSpy('isActive');
mockStatusCapability = jasmine.createSpyObj( mockStatusCapability = jasmine.createSpyObj(
@@ -76,23 +76,23 @@ define(
"contextCapability", "contextCapability",
["getParent"] ["getParent"]
); );
mockContextCapability.getParent.and.returnValue(mockParentObject); mockContextCapability.getParent.andReturn(mockParentObject);
capabilities = { capabilities = {
context: mockContextCapability, context: mockContextCapability,
status: mockStatusCapability status: mockStatusCapability
}; };
mockDomainObject.hasCapability.and.callFake(function (name) { mockDomainObject.hasCapability.andCallFake(function (name) {
return capabilities[name] !== undefined; return capabilities[name] !== undefined;
}); });
mockDomainObject.getCapability.and.callFake(function (name) { mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name]; return capabilities[name];
}); });
mockParentObject.getCapability.and.returnValue(mockParentStatus); mockParentObject.getCapability.andReturn(mockParentStatus);
mockParentObject.hasCapability.and.returnValue(false); mockParentObject.hasCapability.andReturn(false);
capability = new EditorCapability( capability = new EditorCapability(
mockTransactionService, mockTransactionService,
@@ -112,18 +112,18 @@ define(
it("uses editing status to determine editing context root", function () { it("uses editing status to determine editing context root", function () {
capability.edit(); capability.edit();
mockStatusCapability.get.and.returnValue(false); mockStatusCapability.get.andReturn(false);
expect(capability.isEditContextRoot()).toBe(false); expect(capability.isEditContextRoot()).toBe(false);
mockStatusCapability.get.and.returnValue(true); mockStatusCapability.get.andReturn(true);
expect(capability.isEditContextRoot()).toBe(true); expect(capability.isEditContextRoot()).toBe(true);
}); });
it("inEditingContext returns true if parent object is being" + it("inEditingContext returns true if parent object is being" +
" edited", function () { " edited", function () {
mockStatusCapability.get.and.returnValue(false); mockStatusCapability.get.andReturn(false);
mockParentStatus.get.and.returnValue(false); mockParentStatus.get.andReturn(false);
expect(capability.inEditContext()).toBe(false); expect(capability.inEditContext()).toBe(false);
mockParentStatus.get.and.returnValue(true); mockParentStatus.get.andReturn(true);
expect(capability.inEditContext()).toBe(true); expect(capability.inEditContext()).toBe(true);
}); });
@@ -142,7 +142,7 @@ define(
describe("finish", function () { describe("finish", function () {
beforeEach(function () { beforeEach(function () {
mockTransactionService.isActive.and.returnValue(true); mockTransactionService.isActive.andReturn(true);
capability.edit(); capability.edit();
capability.finish(); capability.finish();
}); });
@@ -156,7 +156,7 @@ define(
describe("finish", function () { describe("finish", function () {
beforeEach(function () { beforeEach(function () {
mockTransactionService.isActive.and.returnValue(false); mockTransactionService.isActive.andReturn(false);
capability.edit(); capability.edit();
}); });
@@ -175,15 +175,15 @@ define(
var model = {}; var model = {};
beforeEach(function () { beforeEach(function () {
mockDomainObject.getModel.and.returnValue(model); mockDomainObject.getModel.andReturn(model);
capability.edit(); capability.edit();
capability.finish(); capability.finish();
}); });
it("returns true if the object has been modified since it" + it("returns true if the object has been modified since it" +
" was last persisted", function () { " was last persisted", function () {
mockTransactionService.size.and.returnValue(0); mockTransactionService.size.andReturn(0);
expect(capability.dirty()).toBe(false); expect(capability.dirty()).toBe(false);
mockTransactionService.size.and.returnValue(1); mockTransactionService.size.andReturn(1);
expect(capability.dirty()).toBe(true); expect(capability.dirty()).toBe(true);
}); });
}); });

View File

@@ -37,7 +37,7 @@ define(
mockQ = {}; mockQ = {};
mockTransactionService = {}; mockTransactionService = {};
mockCapabilityService = jasmine.createSpyObj("capabilityService", ["getCapabilities"]); mockCapabilityService = jasmine.createSpyObj("capabilityService", ["getCapabilities"]);
mockCapabilityService.getCapabilities.and.returnValue({ mockCapabilityService.getCapabilities.andReturn({
persistence: function () {} persistence: function () {}
}); });

View File

@@ -47,7 +47,7 @@ define(
testId = "test-id"; testId = "test-id";
mockQ = jasmine.createSpyObj("$q", ["when"]); mockQ = jasmine.createSpyObj("$q", ["when"]);
mockQ.when.and.callFake(function (val) { mockQ.when.andCallFake(function (val) {
return fastPromise(val); return fastPromise(val);
}); });
mockTransactionManager = jasmine.createSpyObj( mockTransactionManager = jasmine.createSpyObj(
@@ -58,15 +58,15 @@ define(
"persistenceCapability", "persistenceCapability",
["persist", "refresh", "getSpace"] ["persist", "refresh", "getSpace"]
); );
mockPersistence.persist.and.returnValue(fastPromise()); mockPersistence.persist.andReturn(fastPromise());
mockPersistence.refresh.and.returnValue(fastPromise()); mockPersistence.refresh.andReturn(fastPromise());
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
"domainObject", "domainObject",
["getModel", "getId"] ["getModel", "getId"]
); );
mockDomainObject.getModel.and.returnValue({persisted: 1}); mockDomainObject.getModel.andReturn({persisted: 1});
mockDomainObject.getId.and.returnValue(testId); mockDomainObject.getId.andReturn(testId);
capability = new TransactionalPersistenceCapability( capability = new TransactionalPersistenceCapability(
mockQ, mockQ,
@@ -78,24 +78,24 @@ define(
it("if no transaction is active, passes through to persistence" + it("if no transaction is active, passes through to persistence" +
" provider", function () { " provider", function () {
mockTransactionManager.isActive.and.returnValue(false); mockTransactionManager.isActive.andReturn(false);
capability.persist(); capability.persist();
expect(mockPersistence.persist).toHaveBeenCalled(); expect(mockPersistence.persist).toHaveBeenCalled();
}); });
it("if transaction is active, persist and cancel calls are" + it("if transaction is active, persist and cancel calls are" +
" queued", function () { " queued", function () {
mockTransactionManager.isActive.and.returnValue(true); mockTransactionManager.isActive.andReturn(true);
capability.persist(); capability.persist();
expect(mockTransactionManager.addToTransaction).toHaveBeenCalled(); expect(mockTransactionManager.addToTransaction).toHaveBeenCalled();
mockTransactionManager.addToTransaction.calls.mostRecent().args[1](); mockTransactionManager.addToTransaction.mostRecentCall.args[1]();
expect(mockPersistence.persist).toHaveBeenCalled(); expect(mockPersistence.persist).toHaveBeenCalled();
mockTransactionManager.addToTransaction.calls.mostRecent().args[2](); mockTransactionManager.addToTransaction.mostRecentCall.args[2]();
expect(mockPersistence.refresh).toHaveBeenCalled(); expect(mockPersistence.refresh).toHaveBeenCalled();
}); });
it("wraps getSpace", function () { it("wraps getSpace", function () {
mockPersistence.getSpace.and.returnValue('foo'); mockPersistence.getSpace.andReturn('foo');
expect(capability.getSpace()).toEqual('foo'); expect(capability.getSpace()).toEqual('foo');
}); });

View File

@@ -38,7 +38,7 @@ define(
jasmine.createSpyObj("mockSaveAction", ["getMetadata", "perform"]) jasmine.createSpyObj("mockSaveAction", ["getMetadata", "perform"])
]; ];
mockedSaveActions.forEach(function (action) { mockedSaveActions.forEach(function (action) {
action.getMetadata.and.returnValue(mockSaveActionMetadata); action.getMetadata.andReturn(mockSaveActionMetadata);
}); });
return mockedSaveActions; return mockedSaveActions;
} else if (actionContext.category === "conclude-editing") { } else if (actionContext.category === "conclude-editing") {
@@ -54,14 +54,14 @@ define(
beforeEach(function () { beforeEach(function () {
mockActions = jasmine.createSpyObj("action", ["getActions"]); mockActions = jasmine.createSpyObj("action", ["getActions"]);
mockActions.getActions.and.callFake(fakeGetActions); mockActions.getActions.andCallFake(fakeGetActions);
mockScope = jasmine.createSpyObj("$scope", ["$watch"]); mockScope = jasmine.createSpyObj("$scope", ["$watch"]);
mockScope.action = mockActions; mockScope.action = mockActions;
controller = new EditActionController(mockScope); controller = new EditActionController(mockScope);
}); });
function makeControllerUpdateActions() { function makeControllerUpdateActions() {
mockScope.$watch.calls.mostRecent().args[1](); mockScope.$watch.mostRecentCall.args[1]();
} }
it("watches scope that may change applicable actions", function () { it("watches scope that may change applicable actions", function () {

View File

@@ -61,17 +61,17 @@ define(
mockLocation = jasmine.createSpyObj('$location', mockLocation = jasmine.createSpyObj('$location',
["search"] ["search"]
); );
mockLocation.search.and.returnValue({"view": "fixed"}); mockLocation.search.andReturn({"view": "fixed"});
mockNavigationService = jasmine.createSpyObj('navigationService', mockNavigationService = jasmine.createSpyObj('navigationService',
["checkBeforeNavigation"] ["checkBeforeNavigation"]
); );
removeCheck = jasmine.createSpy('removeCheck'); removeCheck = jasmine.createSpy('removeCheck');
mockNavigationService.checkBeforeNavigation.and.returnValue(removeCheck); mockNavigationService.checkBeforeNavigation.andReturn(removeCheck);
mockObject.getId.and.returnValue("test"); mockObject.getId.andReturn("test");
mockObject.getModel.and.returnValue({ name: "Test object" }); mockObject.getModel.andReturn({ name: "Test object" });
mockObject.getCapability.and.callFake(function (key) { mockObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key]; return mockCapabilities[key];
}); });
@@ -81,10 +81,10 @@ define(
{ key: 'xyz' } { key: 'xyz' }
]; ];
mockObject.useCapability.and.callFake(function (c) { mockObject.useCapability.andCallFake(function (c) {
return (c === 'view') && testViews; return (c === 'view') && testViews;
}); });
mockLocation.search.and.returnValue({ view: 'def' }); mockLocation.search.andReturn({ view: 'def' });
mockScope.domainObject = mockObject; mockScope.domainObject = mockObject;
@@ -99,17 +99,17 @@ define(
expect(mockNavigationService.checkBeforeNavigation) expect(mockNavigationService.checkBeforeNavigation)
.toHaveBeenCalledWith(jasmine.any(Function)); .toHaveBeenCalledWith(jasmine.any(Function));
var checkFn = mockNavigationService.checkBeforeNavigation.calls.mostRecent().args[0]; var checkFn = mockNavigationService.checkBeforeNavigation.mostRecentCall.args[0];
mockEditorCapability.isEditContextRoot.and.returnValue(false); mockEditorCapability.isEditContextRoot.andReturn(false);
mockEditorCapability.dirty.and.returnValue(false); mockEditorCapability.dirty.andReturn(false);
expect(checkFn()).toBe("Continuing will cause the loss of any unsaved changes."); expect(checkFn()).toBe("Continuing will cause the loss of any unsaved changes.");
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
expect(checkFn()).toBe("Continuing will cause the loss of any unsaved changes."); expect(checkFn()).toBe("Continuing will cause the loss of any unsaved changes.");
mockEditorCapability.dirty.and.returnValue(true); mockEditorCapability.dirty.andReturn(true);
expect(checkFn()) expect(checkFn())
.toBe("Continuing will cause the loss of any unsaved changes."); .toBe("Continuing will cause the loss of any unsaved changes.");
@@ -119,7 +119,7 @@ define(
expect(mockScope.$on) expect(mockScope.$on)
.toHaveBeenCalledWith("$destroy", jasmine.any(Function)); .toHaveBeenCalledWith("$destroy", jasmine.any(Function));
mockScope.$on.calls.mostRecent().args[1](); mockScope.$on.mostRecentCall.args[1]();
expect(mockEditorCapability.finish).toHaveBeenCalled(); expect(mockEditorCapability.finish).toHaveBeenCalled();
expect(removeCheck).toHaveBeenCalled(); expect(removeCheck).toHaveBeenCalled();

View File

@@ -41,13 +41,13 @@ define(
['getTrueRoot'] ['getTrueRoot']
); );
mockDomainObject.getId.and.returnValue('test-id'); mockDomainObject.getId.andReturn('test-id');
mockDomainObject.getCapability.and.returnValue(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
// Return a new instance of the root object each time // Return a new instance of the root object each time
mockContext.getTrueRoot.and.callFake(function () { mockContext.getTrueRoot.andCallFake(function () {
var mockRoot = jasmine.createSpyObj('root', ['getId']); var mockRoot = jasmine.createSpyObj('root', ['getId']);
mockRoot.getId.and.returnValue('root-id'); mockRoot.getId.andReturn('root-id');
return mockRoot; return mockRoot;
}); });
@@ -63,7 +63,7 @@ define(
}); });
it("exposes the root object found via the object's context capability", function () { it("exposes the root object found via the object's context capability", function () {
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
// Verify that the correct capability was used // Verify that the correct capability was used
expect(mockDomainObject.getCapability) expect(mockDomainObject.getCapability)
@@ -76,10 +76,10 @@ define(
it("preserves the same root instance to avoid excessive refreshing", function () { it("preserves the same root instance to avoid excessive refreshing", function () {
var firstRoot; var firstRoot;
// Expose the domain object // Expose the domain object
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
firstRoot = controller.getRoot(); firstRoot = controller.getRoot();
// Update! // Update!
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
// Should still have the same object instance, to avoid // Should still have the same object instance, to avoid
// triggering the watch used by the template we're supporting // triggering the watch used by the template we're supporting
expect(controller.getRoot()).toBe(firstRoot); expect(controller.getRoot()).toBe(firstRoot);
@@ -90,18 +90,18 @@ define(
it("updates the root when it changes", function () { it("updates the root when it changes", function () {
var firstRoot; var firstRoot;
// Expose the domain object // Expose the domain object
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
firstRoot = controller.getRoot(); firstRoot = controller.getRoot();
// Change the exposed root // Change the exposed root
mockContext.getTrueRoot.and.callFake(function () { mockContext.getTrueRoot.andCallFake(function () {
var mockRoot = jasmine.createSpyObj('root', ['getId']); var mockRoot = jasmine.createSpyObj('root', ['getId']);
mockRoot.getId.and.returnValue('other-root-id'); mockRoot.getId.andReturn('other-root-id');
return mockRoot; return mockRoot;
}); });
// Update! // Update!
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
// Should still have the same object instance, to avoid // Should still have the same object instance, to avoid
// triggering the watch used by the template we're supporting // triggering the watch used by the template we're supporting

View File

@@ -63,13 +63,13 @@ define(
mockMutationCapability = jasmine.createSpyObj("mutationCapability", [ mockMutationCapability = jasmine.createSpyObj("mutationCapability", [
"listen" "listen"
]); ]);
mockMutationCapability.listen.and.returnValue(mockUnlisten); mockMutationCapability.listen.andReturn(mockUnlisten);
mockDomainObject = jasmine.createSpyObj("domainObject", [ mockDomainObject = jasmine.createSpyObj("domainObject", [
"getCapability", "getCapability",
"useCapability" "useCapability"
]); ]);
mockDomainObject.useCapability.and.returnValue(mockCompositionCapability); mockDomainObject.useCapability.andReturn(mockCompositionCapability);
mockDomainObject.getCapability.and.returnValue(mockMutationCapability); mockDomainObject.getCapability.andReturn(mockMutationCapability);
mockScope = jasmine.createSpyObj("$scope", ['$on']); mockScope = jasmine.createSpyObj("$scope", ['$on']);
mockSelection = jasmine.createSpyObj("selection", [ mockSelection = jasmine.createSpyObj("selection", [
@@ -77,7 +77,7 @@ define(
'off', 'off',
'get' 'get'
]); ]);
mockSelection.get.and.returnValue([]); mockSelection.get.andReturn([]);
mockOpenMCT = { mockOpenMCT = {
selection: mockSelection selection: mockSelection
}; };
@@ -88,7 +88,7 @@ define(
} }
}; };
spyOn(ElementsController.prototype, 'refreshComposition').and.callThrough(); spyOn(ElementsController.prototype, 'refreshComposition').andCallThrough();
controller = new ElementsController(mockScope, mockOpenMCT); controller = new ElementsController(mockScope, mockOpenMCT);
}); });
@@ -123,29 +123,29 @@ define(
}); });
it("refreshes composition on selection", function () { it("refreshes composition on selection", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); mockOpenMCT.selection.on.mostRecentCall.args[1](selectable);
expect(ElementsController.prototype.refreshComposition).toHaveBeenCalledWith(mockDomainObject); expect(ElementsController.prototype.refreshComposition).toHaveBeenCalledWith(mockDomainObject);
}); });
it("listens on mutation and refreshes composition", function () { it("listens on mutation and refreshes composition", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); mockOpenMCT.selection.on.mostRecentCall.args[1](selectable);
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('mutation'); expect(mockDomainObject.getCapability).toHaveBeenCalledWith('mutation');
expect(mockMutationCapability.listen).toHaveBeenCalled(); expect(mockMutationCapability.listen).toHaveBeenCalled();
expect(ElementsController.prototype.refreshComposition.calls.count()).toBe(1); expect(ElementsController.prototype.refreshComposition.calls.length).toBe(1);
mockMutationCapability.listen.calls.mostRecent().args[0](mockDomainObject); mockMutationCapability.listen.mostRecentCall.args[0](mockDomainObject);
expect(ElementsController.prototype.refreshComposition.calls.count()).toBe(2); expect(ElementsController.prototype.refreshComposition.calls.length).toBe(2);
}); });
it("cleans up mutation listener when selection changes", function () { it("cleans up mutation listener when selection changes", function () {
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); mockOpenMCT.selection.on.mostRecentCall.args[1](selectable);
expect(mockMutationCapability.listen).toHaveBeenCalled(); expect(mockMutationCapability.listen).toHaveBeenCalled();
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); mockOpenMCT.selection.on.mostRecentCall.args[1](selectable);
expect(mockUnlisten).toHaveBeenCalled(); expect(mockUnlisten).toHaveBeenCalled();
}); });
@@ -156,7 +156,7 @@ define(
elementProxy: {} elementProxy: {}
} }
}; };
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable); mockOpenMCT.selection.on.mostRecentCall.args[1](selectable);
expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation'); expect(mockDomainObject.getCapability).not.toHaveBeenCalledWith('mutation');
}); });
@@ -167,13 +167,13 @@ define(
firstCompositionCallback, firstCompositionCallback,
secondCompositionCallback; secondCompositionCallback;
spyOn(mockCompositionCapability, "then").and.callThrough(); spyOn(mockCompositionCapability, "then").andCallThrough();
controller.refreshComposition(mockDomainObject); controller.refreshComposition(mockDomainObject);
controller.refreshComposition(mockDomainObject); controller.refreshComposition(mockDomainObject);
firstCompositionCallback = mockCompositionCapability.then.calls.all()[0].args[0]; firstCompositionCallback = mockCompositionCapability.then.calls[0].args[0];
secondCompositionCallback = mockCompositionCapability.then.calls.all()[1].args[0]; secondCompositionCallback = mockCompositionCapability.then.calls[1].args[0];
secondCompositionCallback(secondMockCompositionObjects); secondCompositionCallback(secondMockCompositionObjects);
firstCompositionCallback(mockCompositionObjects); firstCompositionCallback(mockCompositionObjects);

View File

@@ -51,9 +51,9 @@ define(
"hasFeature" "hasFeature"
] ]
); );
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
mockType.getName.and.returnValue(name); mockType.getName.andReturn(name);
mockType.getKey.and.returnValue(name); mockType.getKey.andReturn(name);
return mockType; return mockType;
} }
@@ -77,7 +77,7 @@ define(
mockTypeMap[type.getKey()] = type; mockTypeMap[type.getKey()] = type;
}); });
mockTypeService.getType.and.callFake(function (key) { mockTypeService.getType.andCallFake(function (key) {
return mockTypeMap[key]; return mockTypeMap[key];
}); });

View File

@@ -49,8 +49,8 @@ define(
"hasFeature" "hasFeature"
] ]
); );
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
mockType.getName.and.returnValue(name); mockType.getName.andReturn(name);
return mockType; return mockType;
} }
@@ -74,11 +74,11 @@ define(
return mockPolicyMap[type.getName()]; return mockPolicyMap[type.getName()];
}; };
mockPolicyService.allow.and.callFake(function (category, type) { mockPolicyService.allow.andCallFake(function (category, type) {
return category === "creation" && mockCreationPolicy(type) ? true : false; return category === "creation" && mockCreationPolicy(type) ? true : false;
}); });
mockTypeService.listTypes.and.returnValue(mockTypes); mockTypeService.listTypes.andReturn(mockTypes);
provider = new CreateActionProvider( provider = new CreateActionProvider(
mockTypeService, mockTypeService,

View File

@@ -77,10 +77,10 @@ define(
"useCapability" "useCapability"
] ]
); );
mockDomainObject.hasCapability.and.callFake(function (name) { mockDomainObject.hasCapability.andCallFake(function (name) {
return !!capabilities[name]; return !!capabilities[name];
}); });
mockDomainObject.getCapability.and.callFake(function (name) { mockDomainObject.getCapability.andCallFake(function (name) {
return capabilities[name]; return capabilities[name];
}); });
mockSaveAction = jasmine.createSpyObj( mockSaveAction = jasmine.createSpyObj(
@@ -117,14 +117,14 @@ define(
mockContext = { mockContext = {
domainObject: mockParent domainObject: mockParent
}; };
mockParent.useCapability.and.returnValue(mockDomainObject); mockParent.useCapability.andReturn(mockDomainObject);
mockType.getKey.and.returnValue("test"); mockType.getKey.andReturn("test");
mockType.getCssClass.and.returnValue("icon-telemetry"); mockType.getCssClass.andReturn("icon-telemetry");
mockType.getDescription.and.returnValue("a test type"); mockType.getDescription.andReturn("a test type");
mockType.getName.and.returnValue("Test"); mockType.getName.andReturn("Test");
mockType.getProperties.and.returnValue([]); mockType.getProperties.andReturn([]);
mockType.getInitialModel.and.returnValue({}); mockType.getInitialModel.andReturn({});
action = new CreateAction( action = new CreateAction(
mockType, mockType,
@@ -144,7 +144,7 @@ define(
describe("the perform function", function () { describe("the perform function", function () {
var promise = jasmine.createSpyObj("promise", ["then"]); var promise = jasmine.createSpyObj("promise", ["then"]);
beforeEach(function () { beforeEach(function () {
capabilities.action.getActions.and.returnValue([mockEditAction]); capabilities.action.getActions.andReturn([mockEditAction]);
}); });
it("uses the instantiation capability when performed", function () { it("uses the instantiation capability when performed", function () {
@@ -159,30 +159,30 @@ define(
it("uses the save-as action if object does not have an edit action" + it("uses the save-as action if object does not have an edit action" +
" available", function () { " available", function () {
capabilities.action.getActions.and.returnValue([]); capabilities.action.getActions.andReturn([]);
capabilities.action.perform.and.returnValue(mockPromise(undefined)); capabilities.action.perform.andReturn(mockPromise(undefined));
capabilities.editor.save.and.returnValue(promise); capabilities.editor.save.andReturn(promise);
action.perform(); action.perform();
expect(capabilities.action.perform).toHaveBeenCalledWith("save-as"); expect(capabilities.action.perform).toHaveBeenCalledWith("save-as");
}); });
describe("uses to editor capability", function () { describe("uses to editor capability", function () {
beforeEach(function () { beforeEach(function () {
capabilities.action.getActions.and.returnValue([]); capabilities.action.getActions.andReturn([]);
capabilities.action.perform.and.returnValue(promise); capabilities.action.perform.andReturn(promise);
capabilities.editor.save.and.returnValue(promise); capabilities.editor.save.andReturn(promise);
}); });
it("to save the edit if user saves dialog", function () { it("to save the edit if user saves dialog", function () {
action.perform(); action.perform();
expect(promise.then).toHaveBeenCalled(); expect(promise.then).toHaveBeenCalled();
promise.then.calls.mostRecent().args[0](); promise.then.mostRecentCall.args[0]();
expect(capabilities.editor.save).toHaveBeenCalled(); expect(capabilities.editor.save).toHaveBeenCalled();
}); });
it("to finish the edit if user cancels dialog", function () { it("to finish the edit if user cancels dialog", function () {
action.perform(); action.perform();
promise.then.calls.mostRecent().args[1](); promise.then.mostRecentCall.args[1]();
expect(capabilities.editor.finish).toHaveBeenCalled(); expect(capabilities.editor.finish).toHaveBeenCalled();
}); });
}); });

View File

@@ -49,10 +49,10 @@ define(
it("populates the scope with create actions", function () { it("populates the scope with create actions", function () {
mockScope.action = mockActions; mockScope.action = mockActions;
mockActions.getActions.and.returnValue(["a", "b", "c"]); mockActions.getActions.andReturn(["a", "b", "c"]);
// Call the watch // Call the watch
mockScope.$watch.calls.mostRecent().args[1](); mockScope.$watch.mostRecentCall.args[1]();
// Should have grouped and ungrouped actions in scope now // Should have grouped and ungrouped actions in scope now
expect(mockScope.createActions.length).toEqual(3); expect(mockScope.createActions.length).toEqual(3);

View File

@@ -41,10 +41,10 @@ define(
"property" + name, "property" + name,
["getDefinition", "getValue", "setValue"] ["getDefinition", "getValue", "setValue"]
); );
mockProperty.getDefinition.and.returnValue({ mockProperty.getDefinition.andReturn({
control: "textfield" control: "textfield"
}); });
mockProperty.getValue.and.returnValue(name); mockProperty.getValue.andReturn(name);
return mockProperty; return mockProperty;
} }
@@ -74,12 +74,12 @@ define(
testModel = { someKey: "some value" }; testModel = { someKey: "some value" };
mockType.getKey.and.returnValue("test"); mockType.getKey.andReturn("test");
mockType.getCssClass.and.returnValue("icon-telemetry"); mockType.getCssClass.andReturn("icon-telemetry");
mockType.getDescription.and.returnValue("a test type"); mockType.getDescription.andReturn("a test type");
mockType.getName.and.returnValue("Test"); mockType.getName.andReturn("Test");
mockType.getInitialModel.and.returnValue(testModel); mockType.getInitialModel.andReturn(testModel);
mockType.getProperties.and.returnValue(mockProperties); mockType.getProperties.andReturn(mockProperties);
mockDomainObject = jasmine.createSpyObj( mockDomainObject = jasmine.createSpyObj(
'domainObject', 'domainObject',
@@ -87,9 +87,9 @@ define(
); );
//Mocking the getCapability('type') call //Mocking the getCapability('type') call
mockDomainObject.getCapability.and.returnValue(mockType); mockDomainObject.getCapability.andReturn(mockType);
mockDomainObject.useCapability.and.returnValue(); mockDomainObject.useCapability.andReturn();
mockDomainObject.getModel.and.returnValue(testModel); mockDomainObject.getModel.andReturn(testModel);
wizard = new CreateWizard( wizard = new CreateWizard(
mockDomainObject, mockDomainObject,
@@ -147,11 +147,9 @@ define(
"C": "ValueC" "C": "ValueC"
}, },
compareModel = wizard.createModel(formValue); compareModel = wizard.createModel(formValue);
//populateObjectFromInput adds a .location attribute that is not added by createModel.
compareModel.location = undefined;
wizard.populateObjectFromInput(formValue); wizard.populateObjectFromInput(formValue);
expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function)); expect(mockDomainObject.useCapability).toHaveBeenCalledWith('mutation', jasmine.any(Function));
expect(mockDomainObject.useCapability.calls.mostRecent().args[1]()).toEqual(compareModel); expect(mockDomainObject.useCapability.mostRecentCall.args[1]()).toEqual(compareModel);
}); });
it("validates selection types using policy", function () { it("validates selection types using policy", function () {
@@ -170,7 +168,7 @@ define(
rows = structure.sections[sections.length - 1].rows, rows = structure.sections[sections.length - 1].rows,
locationRow = rows[rows.length - 1]; locationRow = rows[rows.length - 1];
mockDomainObj.getCapability.and.returnValue(mockOtherType); mockDomainObj.getCapability.andReturn(mockOtherType);
locationRow.validate(mockDomainObj); locationRow.validate(mockDomainObj);
// Should check policy to see if the user-selected location // Should check policy to see if the user-selected location

View File

@@ -38,12 +38,12 @@ define(
}); });
it("allows creation of types with the creation feature", function () { it("allows creation of types with the creation feature", function () {
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.andReturn(true);
expect(policy.allow(mockType)).toBeTruthy(); expect(policy.allow(mockType)).toBeTruthy();
}); });
it("disallows creation of types without the creation feature", function () { it("disallows creation of types without the creation feature", function () {
mockType.hasFeature.and.returnValue(false); mockType.hasFeature.andReturn(false);
expect(policy.allow(mockType)).toBeFalsy(); expect(policy.allow(mockType)).toBeFalsy();
}); });
}); });

View File

@@ -103,33 +103,33 @@ define(
["persist", "getSpace"] ["persist", "getSpace"]
); );
mockParentObject.getCapability.and.callFake(function (key) { mockParentObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key]; return mockCapabilities[key];
}); });
mockParentObject.useCapability.and.callFake(function (key, value) { mockParentObject.useCapability.andCallFake(function (key, value) {
return mockCapabilities[key].invoke(value); return mockCapabilities[key].invoke(value);
}); });
mockParentObject.getId.and.returnValue('parentId'); mockParentObject.getId.andReturn('parentId');
mockNewObject.getId.and.returnValue('newId'); mockNewObject.getId.andReturn('newId');
mockNewObject.getCapability.and.callFake(function (c) { mockNewObject.getCapability.andCallFake(function (c) {
return c === 'persistence' ? return c === 'persistence' ?
mockNewPersistenceCapability : undefined; mockNewPersistenceCapability : undefined;
}); });
mockPersistenceCapability.persist mockPersistenceCapability.persist
.and.returnValue(mockPromise(true)); .andReturn(mockPromise(true));
mockNewPersistenceCapability.persist mockNewPersistenceCapability.persist
.and.returnValue(mockPromise(true)); .andReturn(mockPromise(true));
mockMutationCapability.invoke.and.returnValue(mockPromise(true)); mockMutationCapability.invoke.andReturn(mockPromise(true));
mockPersistenceCapability.getSpace.and.returnValue("testSpace"); mockPersistenceCapability.getSpace.andReturn("testSpace");
mockCompositionCapability.invoke.and.returnValue( mockCompositionCapability.invoke.andReturn(
mockPromise([mockNewObject]) mockPromise([mockNewObject])
); );
mockCompositionCapability.add.and.returnValue(mockPromise(true)); mockCompositionCapability.add.andReturn(mockPromise(true));
mockCreationCapability.instantiate.and.returnValue(mockNewObject); mockCreationCapability.instantiate.andReturn(mockNewObject);
mockCreationCapability.invoke.and.callFake(function (model) { mockCreationCapability.invoke.andCallFake(function (model) {
return mockCreationCapability.instantiate(model); return mockCreationCapability.instantiate(model);
}); });
@@ -163,10 +163,10 @@ define(
mockCallback = jasmine.createSpy('callback'); mockCallback = jasmine.createSpy('callback');
// Act as if the object had been created // Act as if the object had been created
mockCompositionCapability.add.and.callFake(function (id) { mockCompositionCapability.add.andCallFake(function (id) {
mockDomainObject.getId.and.returnValue(id); mockDomainObject.getId.andReturn(id);
mockCompositionCapability.invoke mockCompositionCapability.invoke
.and.returnValue(mockPromise([mockDomainObject])); .andReturn(mockPromise([mockDomainObject]));
return mockPromise(mockDomainObject); return mockPromise(mockDomainObject);
}); });
@@ -200,7 +200,7 @@ define(
// created object - this is an error. // created object - this is an error.
var model = { someKey: "some value" }; var model = { someKey: "some value" };
mockCompositionCapability.add.and.returnValue(mockPromise(false)); mockCompositionCapability.add.andReturn(mockPromise(false));
creationService.createObject(model, mockParentObject); creationService.createObject(model, mockParentObject);

View File

@@ -64,9 +64,9 @@ define(
["then"] ["then"]
); );
mockDomainObject.getCapability.and.returnValue(mockContext); mockDomainObject.getCapability.andReturn(mockContext);
mockContext.getRoot.and.returnValue(mockRootObject); mockContext.getRoot.andReturn(mockRootObject);
mockObjectService.getObjects.and.returnValue(getObjectsPromise); mockObjectService.getObjects.andReturn(getObjectsPromise);
mockScope.ngModel = {}; mockScope.ngModel = {};
mockScope.field = "someField"; mockScope.field = "someField";
@@ -76,7 +76,7 @@ define(
describe("when context is available", function () { describe("when context is available", function () {
beforeEach(function () { beforeEach(function () {
mockContext.getRoot.and.returnValue(mockRootObject); mockContext.getRoot.andReturn(mockRootObject);
controller = new LocatorController(mockScope, mockTimeout, mockObjectService); controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
}); });
@@ -96,8 +96,8 @@ define(
it("changes its own model on embedded model updates", function () { it("changes its own model on embedded model updates", function () {
// Need to pass on selection changes as updates to // Need to pass on selection changes as updates to
// the control's value // the control's value
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockScope.ngModel.someField).toEqual(mockDomainObject); expect(mockScope.ngModel.someField).toEqual(mockDomainObject);
expect(mockScope.rootObject).toEqual(mockRootObject); expect(mockScope.rootObject).toEqual(mockRootObject);
@@ -109,11 +109,11 @@ define(
it("rejects changes which fail validation", function () { it("rejects changes which fail validation", function () {
mockScope.structure = { validate: jasmine.createSpy('validate') }; mockScope.structure = { validate: jasmine.createSpy('validate') };
mockScope.structure.validate.and.returnValue(false); mockScope.structure.validate.andReturn(false);
// Pass selection change // Pass selection change
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockScope.structure.validate).toHaveBeenCalled(); expect(mockScope.structure.validate).toHaveBeenCalled();
// Change should have been rejected // Change should have been rejected
@@ -126,13 +126,13 @@ define(
['$setValidity'] ['$setValidity']
); );
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockScope.ngModelController.$setValidity) expect(mockScope.ngModelController.$setValidity)
.toHaveBeenCalledWith(jasmine.any(String), true); .toHaveBeenCalledWith(jasmine.any(String), true);
mockScope.$watch.calls.mostRecent().args[1](undefined); mockScope.$watch.mostRecentCall.args[1](undefined);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockScope.ngModelController.$setValidity) expect(mockScope.ngModelController.$setValidity)
.toHaveBeenCalledWith(jasmine.any(String), false); .toHaveBeenCalledWith(jasmine.any(String), false);
}); });
@@ -141,27 +141,27 @@ define(
var defaultRoot = "DEFAULT_ROOT"; var defaultRoot = "DEFAULT_ROOT";
beforeEach(function () { beforeEach(function () {
mockContext.getRoot.and.returnValue(undefined); mockContext.getRoot.andReturn(undefined);
getObjectsPromise.then.and.callFake(function (callback) { getObjectsPromise.then.andCallFake(function (callback) {
callback({'ROOT': defaultRoot}); callback({'ROOT': defaultRoot});
}); });
controller = new LocatorController(mockScope, mockTimeout, mockObjectService); controller = new LocatorController(mockScope, mockTimeout, mockObjectService);
}); });
it("provides a default context where none is available", function () { it("provides a default context where none is available", function () {
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockScope.rootObject).toBe(defaultRoot); expect(mockScope.rootObject).toBe(defaultRoot);
}); });
it("does not issue redundant requests for the root object", function () { it("does not issue redundant requests for the root object", function () {
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
mockScope.$watch.calls.mostRecent().args[1](undefined); mockScope.$watch.mostRecentCall.args[1](undefined);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
mockScope.$watch.calls.mostRecent().args[1](mockDomainObject); mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
mockTimeout.calls.mostRecent().args[0](); mockTimeout.mostRecentCall.args[0]();
expect(mockObjectService.getObjects.calls.count()) expect(mockObjectService.getObjects.calls.length)
.toEqual(1); .toEqual(1);
}); });

View File

@@ -58,10 +58,10 @@ define(
mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']); mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']); mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockDomainObject.getCapability.and.callFake(function (capability) { mockDomainObject.getCapability.andCallFake(function (capability) {
return capabilities[capability]; return capabilities[capability];
}); });
mockDomainObject.hasCapability.and.callFake(function (capability) { mockDomainObject.hasCapability.andCallFake(function (capability) {
return !!capabilities[capability]; return !!capabilities[capability];
}); });
@@ -71,13 +71,13 @@ define(
plotView = { key: "plot", editable: false }; plotView = { key: "plot", editable: false };
testViews = []; testViews = [];
mockDomainObject.useCapability.and.callFake(function (c) { mockDomainObject.useCapability.andCallFake(function (c) {
// Provide test views, only for the view capability // Provide test views, only for the view capability
return c === 'view' && testViews; return c === 'view' && testViews;
}); });
mockEditAction.getMetadata.and.returnValue({ key: 'edit' }); mockEditAction.getMetadata.andReturn({ key: 'edit' });
mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' }); mockPropertiesAction.getMetadata.andReturn({ key: 'properties' });
testContext = { testContext = {
domainObject: mockDomainObject, domainObject: mockDomainObject,
@@ -111,20 +111,20 @@ define(
it("disallows the edit action when object is already being" + it("disallows the edit action when object is already being" +
" edited", function () { " edited", function () {
testViews = [editableView]; testViews = [editableView];
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
}); });
it("allows editing of panels in plot view", function () { it("allows editing of panels in plot view", function () {
testViews = [plotView]; testViews = [plotView];
mockTypeCapability.getKey.and.returnValue('telemetry.panel'); mockTypeCapability.getKey.andReturn('telemetry.panel');
expect(policy.allow(mockEditAction, testContext)).toBe(true); expect(policy.allow(mockEditAction, testContext)).toBe(true);
}); });
it("disallows editing of plot view when object not a panel type", function () { it("disallows editing of plot view when object not a panel type", function () {
testViews = [plotView]; testViews = [plotView];
mockTypeCapability.getKey.and.returnValue('something.else'); mockTypeCapability.getKey.andReturn('something.else');
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
}); });

View File

@@ -41,20 +41,20 @@ define(
mockEditorCapability = jasmine.createSpyObj("editorCapability", ["isEditContextRoot", "inEditContext"]); mockEditorCapability = jasmine.createSpyObj("editorCapability", ["isEditContextRoot", "inEditContext"]);
navigatedObject = jasmine.createSpyObj("navigatedObject", ["hasCapability", "getCapability"]); navigatedObject = jasmine.createSpyObj("navigatedObject", ["hasCapability", "getCapability"]);
navigatedObject.getCapability.and.returnValue(mockEditorCapability); navigatedObject.getCapability.andReturn(mockEditorCapability);
navigatedObject.hasCapability.and.returnValue(false); navigatedObject.hasCapability.andReturn(false);
mockDomainObject = jasmine.createSpyObj("domainObject", ["hasCapability", "getCapability"]); mockDomainObject = jasmine.createSpyObj("domainObject", ["hasCapability", "getCapability"]);
mockDomainObject.hasCapability.and.returnValue(false); mockDomainObject.hasCapability.andReturn(false);
mockDomainObject.getCapability.and.returnValue(mockEditorCapability); mockDomainObject.getCapability.andReturn(mockEditorCapability);
navigationService = jasmine.createSpyObj("navigationService", ["getNavigation"]); navigationService = jasmine.createSpyObj("navigationService", ["getNavigation"]);
navigationService.getNavigation.and.returnValue(navigatedObject); navigationService.getNavigation.andReturn(navigatedObject);
metadata = {key: "move"}; metadata = {key: "move"};
mockAction = jasmine.createSpyObj("action", ["getMetadata"]); mockAction = jasmine.createSpyObj("action", ["getMetadata"]);
mockAction.getMetadata.and.returnValue(metadata); mockAction.getMetadata.andReturn(metadata);
context = {domainObject: mockDomainObject}; context = {domainObject: mockDomainObject};
@@ -67,8 +67,8 @@ define(
it('Allows "window" action when navigated object in edit mode,' + it('Allows "window" action when navigated object in edit mode,' +
' but selected object not in edit mode ', function () { ' but selected object not in edit mode ', function () {
navigatedObject.hasCapability.and.returnValue(true); navigatedObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
metadata.key = "window"; metadata.key = "window";
expect(policy.allow(mockAction, context)).toBe(true); expect(policy.allow(mockAction, context)).toBe(true);
}); });
@@ -79,12 +79,12 @@ define(
var mockParent = jasmine.createSpyObj("parentObject", ["hasCapability"]), var mockParent = jasmine.createSpyObj("parentObject", ["hasCapability"]),
mockContextCapability = jasmine.createSpyObj("contextCapability", ["getParent"]); mockContextCapability = jasmine.createSpyObj("contextCapability", ["getParent"]);
mockParent.hasCapability.and.returnValue(true); mockParent.hasCapability.andReturn(true);
mockContextCapability.getParent.and.returnValue(mockParent); mockContextCapability.getParent.andReturn(mockParent);
navigatedObject.hasCapability.and.returnValue(true); navigatedObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.and.returnValue(mockContextCapability); mockDomainObject.getCapability.andReturn(mockContextCapability);
mockDomainObject.hasCapability.and.callFake(function (capability) { mockDomainObject.hasCapability.andCallFake(function (capability) {
switch (capability) { switch (capability) {
case "editor": return false; case "editor": return false;
case "context": return true; case "context": return true;
@@ -97,19 +97,19 @@ define(
it('Disallows "move" action when navigated object in edit mode,' + it('Disallows "move" action when navigated object in edit mode,' +
' but selected object not in edit mode ', function () { ' but selected object not in edit mode ', function () {
navigatedObject.hasCapability.and.returnValue(true); navigatedObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
mockEditorCapability.inEditContext.and.returnValue(false); mockEditorCapability.inEditContext.andReturn(false);
metadata.key = "move"; metadata.key = "move";
expect(policy.allow(mockAction, context)).toBe(false); expect(policy.allow(mockAction, context)).toBe(false);
}); });
it('Disallows copy action when navigated object and' + it('Disallows copy action when navigated object and' +
' selected object in edit mode', function () { ' selected object in edit mode', function () {
navigatedObject.hasCapability.and.returnValue(true); navigatedObject.hasCapability.andReturn(true);
mockDomainObject.hasCapability.and.returnValue(true); mockDomainObject.hasCapability.andReturn(true);
mockEditorCapability.isEditContextRoot.and.returnValue(true); mockEditorCapability.isEditContextRoot.andReturn(true);
mockEditorCapability.inEditContext.and.returnValue(true); mockEditorCapability.inEditContext.andReturn(true);
metadata.key = "copy"; metadata.key = "copy";
expect(policy.allow(mockAction, context)).toBe(false); expect(policy.allow(mockAction, context)).toBe(false);

View File

@@ -54,11 +54,11 @@ define(
mockPropertiesAction = jasmine.createSpyObj('properties', ['getMetadata']); mockPropertiesAction = jasmine.createSpyObj('properties', ['getMetadata']);
mockOtherAction = jasmine.createSpyObj('other', ['getMetadata']); mockOtherAction = jasmine.createSpyObj('other', ['getMetadata']);
mockEditAction.getMetadata.and.returnValue({ key: 'edit' }); mockEditAction.getMetadata.andReturn({ key: 'edit' });
mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' }); mockPropertiesAction.getMetadata.andReturn({ key: 'properties' });
mockOtherAction.getMetadata.and.returnValue({key: 'other'}); mockOtherAction.getMetadata.andReturn({key: 'other'});
mockDomainObject.getId.and.returnValue('test:testId'); mockDomainObject.getId.andReturn('test:testId');
testContext = { testContext = {
domainObject: mockDomainObject, domainObject: mockDomainObject,
@@ -69,7 +69,7 @@ define(
}); });
it("Applies to edit action", function () { it("Applies to edit action", function () {
mockObjectAPI.getProvider.and.returnValue({}); mockObjectAPI.getProvider.andReturn({});
expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); expect(mockObjectAPI.getProvider).not.toHaveBeenCalled();
policy.allow(mockEditAction, testContext); policy.allow(mockEditAction, testContext);
@@ -77,7 +77,7 @@ define(
}); });
it("Applies to properties action", function () { it("Applies to properties action", function () {
mockObjectAPI.getProvider.and.returnValue({}); mockObjectAPI.getProvider.andReturn({});
expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); expect(mockObjectAPI.getProvider).not.toHaveBeenCalled();
policy.allow(mockPropertiesAction, testContext); policy.allow(mockPropertiesAction, testContext);
@@ -85,7 +85,7 @@ define(
}); });
it("does not apply to other actions", function () { it("does not apply to other actions", function () {
mockObjectAPI.getProvider.and.returnValue({}); mockObjectAPI.getProvider.andReturn({});
expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); expect(mockObjectAPI.getProvider).not.toHaveBeenCalled();
policy.allow(mockOtherAction, testContext); policy.allow(mockOtherAction, testContext);
@@ -93,10 +93,10 @@ define(
}); });
it("Tests object provider for editability", function () { it("Tests object provider for editability", function () {
mockObjectAPI.getProvider.and.returnValue({}); mockObjectAPI.getProvider.andReturn({});
expect(policy.allow(mockEditAction, testContext)).toBe(false); expect(policy.allow(mockEditAction, testContext)).toBe(false);
expect(mockObjectAPI.getProvider).toHaveBeenCalled(); expect(mockObjectAPI.getProvider).toHaveBeenCalled();
mockObjectAPI.getProvider.and.returnValue({save: function () {}}); mockObjectAPI.getProvider.andReturn({save: function () {}});
expect(policy.allow(mockEditAction, testContext)).toBe(true); expect(policy.allow(mockEditAction, testContext)).toBe(true);
}); });
}); });

View File

@@ -35,12 +35,12 @@ define(
'domainObject', 'domainObject',
['hasCapability', 'getCapability'] ['hasCapability', 'getCapability']
); );
mockDomainObject.getCapability.and.returnValue({ mockDomainObject.getCapability.andReturn({
inEditContext: function () { inEditContext: function () {
return true; return true;
} }
}); });
mockDomainObject.hasCapability.and.callFake(function (c) { mockDomainObject.hasCapability.andCallFake(function (c) {
return (c === 'editor') && testMode; return (c === 'editor') && testMode;
}); });

View File

@@ -52,8 +52,8 @@ define([
'useCapability' 'useCapability'
]); ]);
domainObject.getId.and.returnValue('anId'); domainObject.getId.andReturn('anId');
domainObject.getModel.and.returnValue({name: 'anObject'}); domainObject.getModel.andReturn({name: 'anObject'});
representation = { representation = {
key: 'someRepresentation' key: 'someRepresentation'
@@ -75,7 +75,7 @@ define([
expect(domainObject.useCapability) expect(domainObject.useCapability)
.toHaveBeenCalledWith('mutation', jasmine.any(Function)); .toHaveBeenCalledWith('mutation', jasmine.any(Function));
var mutateValue = domainObject.useCapability.calls.all()[0].args[1](); var mutateValue = domainObject.useCapability.calls[0].args[1]();
expect(mutateValue.configuration.someRepresentation) expect(mutateValue.configuration.someRepresentation)
.toEqual({some: 'config'}); .toEqual({some: 'config'});

View File

@@ -0,0 +1,156 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../../src/representers/EditToolbarRepresenter"],
function (EditToolbarRepresenter) {
describe("The Edit mode toolbar representer", function () {
var mockScope,
mockElement,
testAttrs,
mockUnwatch,
representer,
mockOpenMCT,
mockSelection;
beforeEach(function () {
mockScope = jasmine.createSpyObj(
'$scope',
['$on', '$watch', '$watchCollection', "commit", "$apply"]
);
mockElement = {};
testAttrs = { toolbar: 'testToolbar' };
mockScope.$parent = jasmine.createSpyObj(
'$parent',
['$watch', '$watchCollection']
);
mockUnwatch = jasmine.createSpy('unwatch');
mockScope.$parent.$watchCollection.andReturn(mockUnwatch);
mockSelection = jasmine.createSpyObj("selection", [
'on',
'off',
'get'
]);
mockSelection.get.andReturn([]);
mockOpenMCT = {
selection: mockSelection
};
representer = new EditToolbarRepresenter(
mockOpenMCT,
mockScope,
mockElement,
testAttrs
);
});
it("exposes toolbar state under a attr-defined name", function () {
// A structure/state object should have been added to the
// parent scope under the name provided in the "toolbar"
// attribute
expect(mockScope.$parent.testToolbar).toBeDefined();
});
it("is robust against lack of a toolbar definition", function () {
expect(function () {
representer.represent({});
}).not.toThrow();
});
it("watches for toolbar state changes", function () {
representer.represent({});
expect(mockScope.$watchCollection).toHaveBeenCalledWith(
jasmine.any(Function),
jasmine.any(Function)
);
expect(mockScope.$watchCollection.calls[0].args[0]())
.toBe(mockScope.$parent.testToolbar.state);
});
it("removes state from parent scope on destroy", function () {
// Verify precondition
expect(mockScope.$parent.testToolbar).toBeDefined();
// Destroy the representer
representer.destroy();
// Should have removed toolbar state from view
expect(mockScope.$parent.testToolbar).toBeUndefined();
});
// Verify a simple interaction between selection state and toolbar
// state; more complicated interactions are tested in EditToolbar.
it("conveys state changes", function () {
var testObject = { k: 123 };
// Provide a view which has a toolbar
representer.represent({
toolbar: { sections: [{ items: [{ property: 'k' }] }] }
});
// Update the selection
mockScope.selection.select(testObject);
expect(mockScope.$watchCollection.mostRecentCall.args[0])
.toEqual('selection.all()'); // Make sure we're using right watch
mockScope.$watchCollection.mostRecentCall.args[1]([testObject]);
// Update the state
mockScope.$parent.testToolbar.state[0] = 456;
// Invoke the first watch (assumed to be for toolbar state)
mockScope.$watchCollection.calls[0].args[1](
mockScope.$parent.testToolbar.state
);
// Should have updated the original object
expect(testObject.k).toEqual(456);
// Should have committed the change
expect(mockScope.commit).toHaveBeenCalled();
});
it("does not commit if nothing changed", function () {
var testObject = { k: 123 };
// Provide a view which has a toolbar
representer.represent({
toolbar: { sections: [{ items: [{ property: 'k' }] }] }
});
// Update the selection
mockScope.selection.select(testObject);
expect(mockScope.$watchCollection.mostRecentCall.args[0])
.toEqual('selection.all()'); // Make sure we're using right watch
mockScope.$watchCollection.mostRecentCall.args[1]([testObject]);
// Invoke the first watch (assumed to be for toolbar state)
mockScope.$watchCollection.calls[0].args[1](
mockScope.$parent.testToolbar.state
);
// Should have committed the change
expect(mockScope.commit).not.toHaveBeenCalled();
});
});
}
);

View File

@@ -0,0 +1,128 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
['../../src/representers/EditToolbarSelection'],
function (EditToolbarSelection) {
describe("The Edit mode selection manager", function () {
var testProxy,
testElement,
otherElement,
selection,
mockSelection,
mockOpenMCT,
mockScope;
beforeEach(function () {
testProxy = { someKey: "some value" };
testElement = { someOtherKey: "some other value" };
otherElement = { yetAnotherKey: 42 };
mockSelection = jasmine.createSpyObj("selection", [
// 'select',
'on',
'off',
'get'
]);
mockSelection.get.andReturn([]);
mockOpenMCT = {
selection: mockSelection
};
mockScope = jasmine.createSpyObj('$scope', [
'$on',
'$apply'
]);
selection = new EditToolbarSelection(mockScope, mockOpenMCT);
selection.proxy(testProxy);
});
it("adds the proxy to the selection array", function () {
expect(selection.all()).toEqual([testProxy]);
});
it("exposes view proxy", function () {
expect(selection.proxy()).toBe(testProxy);
});
it("includes selected objects alongside the proxy", function () {
selection.select(testElement);
expect(selection.all()).toEqual([testProxy, testElement]);
});
it("allows elements to be deselected", function () {
selection.select(testElement);
selection.deselect();
expect(selection.all()).toEqual([testProxy]);
});
it("replaces old selections with new ones", function () {
selection.select(testElement);
selection.select(otherElement);
expect(selection.all()).toEqual([testProxy, otherElement]);
});
it("allows retrieval of the current selection", function () {
selection.select(testElement);
expect(selection.get()).toBe(testElement);
selection.select(otherElement);
expect(selection.get()).toBe(otherElement);
});
it("can check if an element is selected", function () {
selection.select(testElement);
expect(selection.selected(testElement)).toBeTruthy();
expect(selection.selected(otherElement)).toBeFalsy();
selection.select(otherElement);
expect(selection.selected(testElement)).toBeFalsy();
expect(selection.selected(otherElement)).toBeTruthy();
});
it("considers the proxy to be selected", function () {
expect(selection.selected(testProxy)).toBeTruthy();
selection.select(testElement);
// Even when something else is selected...
expect(selection.selected(testProxy)).toBeTruthy();
});
it("treats selection of the proxy as a no-op", function () {
selection.select(testProxy);
expect(selection.all()).toEqual([testProxy]);
});
it("cleans up selection on scope destroy", function () {
expect(mockScope.$on).toHaveBeenCalledWith(
'$destroy',
jasmine.any(Function)
);
mockScope.$on.mostRecentCall.args[1]();
expect(mockOpenMCT.selection.off).toHaveBeenCalledWith(
'change',
jasmine.any(Function)
);
});
});
}
);

View File

@@ -25,10 +25,7 @@ define(
function (EditToolbar) { function (EditToolbar) {
describe("An Edit mode toolbar", function () { describe("An Edit mode toolbar", function () {
var mockOpenMCT, var mockCommit,
mockScope,
mockObjects,
mockDomainObject,
testStructure, testStructure,
testAB, testAB,
testABC, testABC,
@@ -38,30 +35,35 @@ define(
testM, testM,
toolbar; toolbar;
function getVisibility(obj) {
return !obj.hidden;
}
beforeEach(function () { beforeEach(function () {
mockOpenMCT = jasmine.createSpy('openmct', ['objects']); mockCommit = jasmine.createSpy('commit');
mockObjects = jasmine.createSpyObj('objects', ['observe']); testStructure = {
mockObjects.observe.and.returnValue(); sections: [
mockOpenMCT.objects = mockObjects; {
mockScope = jasmine.createSpyObj("$scope", [ items: [
"$watchCollection", { name: "A", property: "a", exclusive: true },
"$on" { name: "B", property: "b", exclusive: true },
]); { name: "C", property: "c", exclusive: true }
mockScope.$watchCollection.and.returnValue(); ]
mockDomainObject = jasmine.createSpyObj("domainObject", [ },
'identifier' {
]); items: [
{ name: "X", property: "x" },
testStructure = [ { name: "Y", property: "y", exclusive: true },
{ name: "A", property: "a", domainObject: mockDomainObject }, { name: "Z", property: "z", exclusive: true }
{ name: "B", property: "b", domainObject: mockDomainObject }, ]
{ name: "C", property: "c", domainObject: mockDomainObject }, },
{ name: "X", property: "x", domainObject: mockDomainObject }, {
{ name: "Y", property: "y", domainObject: mockDomainObject }, items: [
{ name: "Z", property: "z", domainObject: mockDomainObject }, { name: "M", method: "m", exclusive: true }
{ name: "M", method: "m", domainObject: mockDomainObject } ]
]; }
]
};
testAB = { a: 0, b: 1 }; testAB = { a: 0, b: 1 };
testABC = { a: 0, b: 1, c: 2 }; testABC = { a: 0, b: 1, c: 2 };
testABC2 = { a: 4, b: 1, c: 2 }; // For inconsistent-state checking testABC2 = { a: 4, b: 1, c: 2 }; // For inconsistent-state checking
@@ -69,17 +71,151 @@ define(
testABCYZ = { a: 0, b: 1, c: 2, y: 'Y!', z: 'Z!' }; testABCYZ = { a: 0, b: 1, c: 2, y: 'Y!', z: 'Z!' };
testM = { m: jasmine.createSpy("method") }; testM = { m: jasmine.createSpy("method") };
toolbar = new EditToolbar(mockScope, mockOpenMCT, testStructure); toolbar = new EditToolbar(testStructure, mockCommit);
});
it("provides properties from the original structure", function () {
expect(
new EditToolbar(testStructure, [testABC])
.getStructure()
.sections[0]
.items[1]
.name
).toEqual("B");
});
// This is needed by mct-toolbar
it("adds keys to form structure", function () {
expect(
new EditToolbar(testStructure, [testABC])
.getStructure()
.sections[0]
.items[1]
.key
).not.toBeUndefined();
});
it("marks empty sections as hidden", function () {
// Verify that all sections are included when applicable...
toolbar.setSelection([testABCXYZ]);
expect(toolbar.getStructure().sections.map(getVisibility))
.toEqual([true, true, false]);
// ...but omitted when only some are applicable
toolbar.setSelection([testABC]);
expect(toolbar.getStructure().sections.map(getVisibility))
.toEqual([true, false, false]);
});
it("reads properties from selections", function () {
var structure, state;
toolbar.setSelection([testABC]);
structure = toolbar.getStructure();
state = toolbar.getState();
expect(state[structure.sections[0].items[0].key])
.toEqual(testABC.a);
expect(state[structure.sections[0].items[1].key])
.toEqual(testABC.b);
expect(state[structure.sections[0].items[2].key])
.toEqual(testABC.c);
});
it("reads properties from getters", function () {
var structure, state;
testABC.a = function () {
return "from a getter!";
};
toolbar.setSelection([testABC]);
structure = toolbar.getStructure();
state = toolbar.getState();
expect(state[structure.sections[0].items[0].key])
.toEqual("from a getter!");
});
it("sets properties on update", function () {
toolbar.setSelection([testABC]);
toolbar.updateState(
toolbar.getStructure().sections[0].items[0].key,
"new value"
);
// Should have updated the underlying object
expect(testABC.a).toEqual("new value");
});
it("invokes setters on update", function () {
var structure;
testABC.a = jasmine.createSpy('a');
toolbar.setSelection([testABC]);
structure = toolbar.getStructure();
toolbar.updateState(
structure.sections[0].items[0].key,
"new value"
);
// Should have updated the underlying object
expect(testABC.a).toHaveBeenCalledWith("new value");
});
it("provides a return value describing update status", function () {
// Should return true if actually updated, otherwise false
var key;
toolbar.setSelection([testABC]);
key = toolbar.getStructure().sections[0].items[0].key;
expect(toolbar.updateState(key, testABC.a)).toBeFalsy();
expect(toolbar.updateState(key, "new value")).toBeTruthy();
});
it("removes inapplicable items", function () {
// First, verify with all items
toolbar.setSelection([testABC]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([true, true, true]);
// Then, try with some items omitted
toolbar.setSelection([testABC, testAB]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([true, true, false]);
});
it("removes inconsistent states", function () {
// Only two of three values match among these selections
toolbar.setSelection([testABC, testABC2]);
expect(toolbar.getStructure().sections[0].items.map(getVisibility))
.toEqual([false, true, true]);
});
it("allows inclusive items", function () {
// One inclusive item is in the set, property 'x' of the
// second section; make sure items are pruned down
// when only some of the selection has x,y,z properties
toolbar.setSelection([testABC, testABCXYZ]);
expect(toolbar.getStructure().sections[1].items.map(getVisibility))
.toEqual([true, false, false]);
});
it("removes inclusive items when there are no matches", function () {
toolbar.setSelection([testABCYZ]);
expect(toolbar.getStructure().sections[1].items.map(getVisibility))
.toEqual([false, true, true]);
}); });
it("adds click functions when a method is specified", function () { it("adds click functions when a method is specified", function () {
var structure = toolbar.getStructure(); toolbar.setSelection([testM]);
expect(structure[6].click).toBeDefined(); // Verify precondition
}); expect(testM.m).not.toHaveBeenCalled();
// Click!
it("adds key for controls that define a property", function () { toolbar.getStructure().sections[2].items[0].click();
var structure = toolbar.getStructure(); // Should have called the underlying function
expect(structure[0].key).toEqual(0); expect(testM.m).toHaveBeenCalled();
// Should also have committed the change
expect(mockCommit).toHaveBeenCalled();
}); });
}); });
} }

View File

@@ -44,10 +44,10 @@ define(
testId = 'test-id'; testId = 'test-id';
mockPromise = jasmine.createSpyObj('promise', ['then']); mockPromise = jasmine.createSpyObj('promise', ['then']);
mockOnCommit.and.returnValue(mockPromise); mockOnCommit.andReturn(mockPromise);
mockOnCancel.and.returnValue(mockPromise); mockOnCancel.andReturn(mockPromise);
mockTransactionService.addToTransaction.and.callFake(function () { mockTransactionService.addToTransaction.andCallFake(function () {
var mockRemove = var mockRemove =
jasmine.createSpy('remove-' + mockRemoves.length); jasmine.createSpy('remove-' + mockRemoves.length);
mockRemoves.push(mockRemove); mockRemoves.push(mockRemove);
@@ -59,7 +59,7 @@ define(
it("delegates isActive calls", function () { it("delegates isActive calls", function () {
[false, true].forEach(function (state) { [false, true].forEach(function (state) {
mockTransactionService.isActive.and.returnValue(state); mockTransactionService.isActive.andReturn(state);
expect(manager.isActive()).toBe(state); expect(manager.isActive()).toBe(state);
}); });
}); });
@@ -84,12 +84,12 @@ define(
it("invokes passed-in callbacks from its own callbacks", function () { it("invokes passed-in callbacks from its own callbacks", function () {
expect(mockOnCommit).not.toHaveBeenCalled(); expect(mockOnCommit).not.toHaveBeenCalled();
mockTransactionService.addToTransaction mockTransactionService.addToTransaction
.calls.mostRecent().args[0](); .mostRecentCall.args[0]();
expect(mockOnCommit).toHaveBeenCalled(); expect(mockOnCommit).toHaveBeenCalled();
expect(mockOnCancel).not.toHaveBeenCalled(); expect(mockOnCancel).not.toHaveBeenCalled();
mockTransactionService.addToTransaction mockTransactionService.addToTransaction
.calls.mostRecent().args[1](); .mostRecentCall.args[1]();
expect(mockOnCancel).toHaveBeenCalled(); expect(mockOnCancel).toHaveBeenCalled();
}); });
@@ -99,7 +99,7 @@ define(
jasmine.createSpy(), jasmine.createSpy(),
jasmine.createSpy() jasmine.createSpy()
); );
expect(mockTransactionService.addToTransaction.calls.count()) expect(mockTransactionService.addToTransaction.calls.length)
.toEqual(1); .toEqual(1);
}); });
@@ -109,7 +109,7 @@ define(
jasmine.createSpy(), jasmine.createSpy(),
jasmine.createSpy() jasmine.createSpy()
); );
expect(mockTransactionService.addToTransaction.calls.count()) expect(mockTransactionService.addToTransaction.calls.length)
.toEqual(2); .toEqual(2);
}); });

View File

@@ -40,7 +40,7 @@ define(
beforeEach(function () { beforeEach(function () {
mockQ = jasmine.createSpyObj("$q", ["all"]); mockQ = jasmine.createSpyObj("$q", ["all"]);
mockQ.all.and.returnValue(fastPromise()); mockQ.all.andReturn(fastPromise());
mockLog = jasmine.createSpyObj("$log", ["error"]); mockLog = jasmine.createSpyObj("$log", ["error"]);
transactionService = new TransactionService(mockQ, mockLog); transactionService = new TransactionService(mockQ, mockLog);
}); });

View File

@@ -92,7 +92,7 @@ define(
describe("and an exception is encountered during commit", function () { describe("and an exception is encountered during commit", function () {
beforeEach(function () { beforeEach(function () {
mockCommit.and.callFake(function () { mockCommit.andCallFake(function () {
throw new Error("test error"); throw new Error("test error");
}); });
transaction.commit(); transaction.commit();

View File

@@ -115,10 +115,8 @@ define([
UTCTimeFormat.prototype.format = function (value) { UTCTimeFormat.prototype.format = function (value) {
if (arguments.length > 1) { if (arguments.length > 1) {
return getScaledFormat(value); return getScaledFormat(value);
} else if (value !== undefined) {
return moment.utc(value).format(DATE_FORMAT) + "Z";
} else { } else {
return value; return moment.utc(value).format(DATE_FORMAT) + "Z";
} }
}; };

View File

@@ -34,6 +34,7 @@ define([
"./src/controllers/ContextMenuController", "./src/controllers/ContextMenuController",
"./src/controllers/ClickAwayController", "./src/controllers/ClickAwayController",
"./src/controllers/ViewSwitcherController", "./src/controllers/ViewSwitcherController",
"./src/controllers/BottomBarController",
"./src/controllers/GetterSetterController", "./src/controllers/GetterSetterController",
"./src/controllers/SelectorController", "./src/controllers/SelectorController",
"./src/controllers/ObjectInspectorController", "./src/controllers/ObjectInspectorController",
@@ -48,14 +49,11 @@ define([
"./src/directives/MCTSplitPane", "./src/directives/MCTSplitPane",
"./src/directives/MCTSplitter", "./src/directives/MCTSplitter",
"./src/directives/MCTTree", "./src/directives/MCTTree",
"./src/directives/MCTIndicators",
"./src/directives/MCTPreview",
"./src/actions/MCTPreviewAction",
"./src/filters/ReverseFilter", "./src/filters/ReverseFilter",
"text!./res/templates/bottombar.html", "text!./res/templates/bottombar.html",
"text!./res/templates/controls/action-button.html", "text!./res/templates/controls/action-button.html",
"text!./res/templates/controls/input-filter.html", "text!./res/templates/controls/input-filter.html",
"text!./res/templates/angular-indicator.html", "text!./res/templates/indicator.html",
"text!./res/templates/message-banner.html", "text!./res/templates/message-banner.html",
"text!./res/templates/progress-bar.html", "text!./res/templates/progress-bar.html",
"text!./res/templates/controls/time-controller.html", "text!./res/templates/controls/time-controller.html",
@@ -71,7 +69,6 @@ define([
"text!./res/templates/controls/selector.html", "text!./res/templates/controls/selector.html",
"text!./res/templates/controls/datetime-picker.html", "text!./res/templates/controls/datetime-picker.html",
"text!./res/templates/controls/datetime-field.html", "text!./res/templates/controls/datetime-field.html",
"text!./res/templates/preview.html",
'legacyRegistry' 'legacyRegistry'
], function ( ], function (
UrlService, UrlService,
@@ -87,6 +84,7 @@ define([
ContextMenuController, ContextMenuController,
ClickAwayController, ClickAwayController,
ViewSwitcherController, ViewSwitcherController,
BottomBarController,
GetterSetterController, GetterSetterController,
SelectorController, SelectorController,
ObjectInspectorController, ObjectInspectorController,
@@ -101,9 +99,6 @@ define([
MCTSplitPane, MCTSplitPane,
MCTSplitter, MCTSplitter,
MCTTree, MCTTree,
MCTIndicators,
MCTPreview,
MCTPreviewAction,
ReverseFilter, ReverseFilter,
bottombarTemplate, bottombarTemplate,
actionButtonTemplate, actionButtonTemplate,
@@ -124,7 +119,6 @@ define([
selectorTemplate, selectorTemplate,
datetimePickerTemplate, datetimePickerTemplate,
datetimeFieldTemplate, datetimeFieldTemplate,
previewTemplate,
legacyRegistry legacyRegistry
) { ) {
@@ -281,6 +275,13 @@ define([
"$timeout" "$timeout"
] ]
}, },
{
"key": "BottomBarController",
"implementation": BottomBarController,
"depends": [
"indicators[]"
]
},
{ {
"key": "GetterSetterController", "key": "GetterSetterController",
"implementation": GetterSetterController, "implementation": GetterSetterController,
@@ -394,37 +395,7 @@ define([
{ {
"key": "mctTree", "key": "mctTree",
"implementation": MCTTree, "implementation": MCTTree,
"depends": ['gestureService', 'openmct'] "depends": ['gestureService']
},
{
"key": "mctIndicators",
"implementation": MCTIndicators,
"depends": ['openmct']
},
{
"key": "mctPreview",
"implementation": MCTPreview,
"depends": [
"$document"
]
}
],
"actions": [
{
"key": "mct-preview-action",
"implementation": MCTPreviewAction,
"name": "Preview",
"cssClass": "hide-in-t-main-view icon-eye-open",
"description": "Preview in large dialog",
"category": [
"contextual",
"view-control"
],
"depends": [
"$compile",
"$rootScope"
],
"priority": "preferred"
} }
], ],
"constants": [ "constants": [
@@ -540,10 +511,6 @@ define([
{ {
"key": "object-inspector", "key": "object-inspector",
"template": objectInspectorTemplate "template": objectInspectorTemplate
},
{
"key": "mct-preview",
"template": previewTemplate
} }
], ],
"controls": [ "controls": [

View File

@@ -2,7 +2,7 @@
"metadata": { "metadata": {
"name": "openmct-symbols-16px", "name": "openmct-symbols-16px",
"lastOpened": 0, "lastOpened": 0,
"created": 1529545133464 "created": 1506973656040
}, },
"iconSets": [ "iconSets": [
{ {
@@ -40,7 +40,7 @@
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 141, "order": 44,
"prevSize": 24, "prevSize": 24,
"name": "icon-arrow-right", "name": "icon-arrow-right",
"id": 39, "id": 39,
@@ -48,7 +48,7 @@
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 142, "order": 41,
"prevSize": 24, "prevSize": 24,
"name": "icon-arrow-double-up", "name": "icon-arrow-double-up",
"id": 36, "id": 36,
@@ -213,7 +213,7 @@
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 144, "order": 29,
"prevSize": 24, "prevSize": 24,
"name": "icon-person", "name": "icon-person",
"id": 24, "id": 24,
@@ -221,7 +221,7 @@
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 147, "order": 86,
"prevSize": 24, "prevSize": 24,
"name": "icon-plus", "name": "icon-plus",
"id": 81, "id": 81,
@@ -268,21 +268,13 @@
"code": 59697, "code": 59697,
"tempChar": "" "tempChar": ""
}, },
{
"order": 148,
"id": 118,
"name": "icon-arrow-right-equilateral",
"prevSize": 24,
"code": 59698,
"tempChar": ""
},
{ {
"order": 48, "order": 48,
"prevSize": 24, "prevSize": 24,
"name": "icon-arrows-out", "name": "icon-arrows-out",
"id": 43, "id": 43,
"code": 921600, "code": 921600,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 49, "order": 49,
@@ -290,7 +282,7 @@
"name": "icon-arrows-right-left", "name": "icon-arrows-right-left",
"id": 44, "id": 44,
"code": 921601, "code": 921601,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 50, "order": 50,
@@ -298,7 +290,7 @@
"name": "icon-arrows-up-down", "name": "icon-arrows-up-down",
"id": 45, "id": 45,
"code": 921602, "code": 921602,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 9, "order": 9,
@@ -306,7 +298,7 @@
"name": "icon-bullet", "name": "icon-bullet",
"id": 4, "id": 4,
"code": 921604, "code": 921604,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 25, "order": 25,
@@ -314,7 +306,7 @@
"name": "icon-calendar", "name": "icon-calendar",
"id": 20, "id": 20,
"code": 921605, "code": 921605,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 30, "order": 30,
@@ -322,7 +314,7 @@
"name": "icon-chain-links", "name": "icon-chain-links",
"id": 25, "id": 25,
"code": 921606, "code": 921606,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 109, "order": 109,
@@ -330,7 +322,7 @@
"prevSize": 24, "prevSize": 24,
"code": 921607, "code": 921607,
"name": "icon-pane-collapse-left", "name": "icon-pane-collapse-left",
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 110, "order": 110,
@@ -338,7 +330,7 @@
"prevSize": 24, "prevSize": 24,
"code": 921608, "code": 921608,
"name": "icon-pane-collapse-right", "name": "icon-pane-collapse-right",
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 5, "order": 5,
@@ -346,7 +338,7 @@
"prevSize": 24, "prevSize": 24,
"code": 921609, "code": 921609,
"name": "icon-download", "name": "icon-download",
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 60, "order": 60,
@@ -354,7 +346,7 @@
"name": "icon-duplicate", "name": "icon-duplicate",
"id": 55, "id": 55,
"code": 921616, "code": 921616,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 61, "order": 61,
@@ -362,7 +354,7 @@
"name": "icon-folder-new", "name": "icon-folder-new",
"id": 56, "id": 56,
"code": 921617, "code": 921617,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 64, "order": 64,
@@ -370,7 +362,7 @@
"name": "icon-fullscreen-expand", "name": "icon-fullscreen-expand",
"id": 59, "id": 59,
"code": 921618, "code": 921618,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 63, "order": 63,
@@ -378,7 +370,7 @@
"name": "icon-fullscreen-collapse", "name": "icon-fullscreen-collapse",
"id": 58, "id": 58,
"code": 921619, "code": 921619,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 67, "order": 67,
@@ -386,23 +378,23 @@
"name": "icon-layers", "name": "icon-layers",
"id": 62, "id": 62,
"code": 921620, "code": 921620,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 145, "order": 69,
"prevSize": 24, "prevSize": 24,
"name": "icon-line-horz", "name": "icon-line-horz",
"id": 64, "id": 64,
"code": 921621, "code": 921621,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 146, "order": 73,
"prevSize": 24, "prevSize": 24,
"name": "icon-magnify", "name": "icon-magnify",
"id": 68, "id": 68,
"code": 921622, "code": 921622,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 71, "order": 71,
@@ -410,7 +402,7 @@
"name": "icon-magnify-in", "name": "icon-magnify-in",
"id": 66, "id": 66,
"code": 921623, "code": 921623,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 72, "order": 72,
@@ -418,7 +410,7 @@
"name": "icon-magnify-out", "name": "icon-magnify-out",
"id": 67, "id": 67,
"code": 921624, "code": 921624,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 74, "order": 74,
@@ -426,7 +418,7 @@
"name": "icon-menu", "name": "icon-menu",
"id": 69, "id": 69,
"code": 921625, "code": 921625,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 75, "order": 75,
@@ -434,7 +426,7 @@
"name": "icon-move", "name": "icon-move",
"id": 70, "id": 70,
"code": 921632, "code": 921632,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 76, "order": 76,
@@ -442,7 +434,7 @@
"name": "icon-new-window", "name": "icon-new-window",
"id": 71, "id": 71,
"code": 921633, "code": 921633,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 26, "order": 26,
@@ -450,7 +442,7 @@
"name": "icon-paint-bucket", "name": "icon-paint-bucket",
"id": 21, "id": 21,
"code": 921634, "code": 921634,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 81, "order": 81,
@@ -458,7 +450,7 @@
"name": "icon-pause", "name": "icon-pause",
"id": 76, "id": 76,
"code": 921635, "code": 921635,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 82, "order": 82,
@@ -466,7 +458,7 @@
"name": "icon-pencil", "name": "icon-pencil",
"id": 77, "id": 77,
"code": 921636, "code": 921636,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 84, "order": 84,
@@ -474,7 +466,7 @@
"name": "icon-play", "name": "icon-play",
"id": 79, "id": 79,
"code": 921637, "code": 921637,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 85, "order": 85,
@@ -482,7 +474,7 @@
"name": "icon-plot-resource", "name": "icon-plot-resource",
"id": 80, "id": 80,
"code": 921638, "code": 921638,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 27, "order": 27,
@@ -490,7 +482,7 @@
"name": "icon-pointer-left", "name": "icon-pointer-left",
"id": 22, "id": 22,
"code": 921639, "code": 921639,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 28, "order": 28,
@@ -498,7 +490,7 @@
"name": "icon-pointer-right", "name": "icon-pointer-right",
"id": 23, "id": 23,
"code": 921640, "code": 921640,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 32, "order": 32,
@@ -506,7 +498,7 @@
"name": "icon-refresh", "name": "icon-refresh",
"id": 27, "id": 27,
"code": 921641, "code": 921641,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 16, "order": 16,
@@ -514,7 +506,7 @@
"name": "icon-save", "name": "icon-save",
"id": 11, "id": 11,
"code": 921648, "code": 921648,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 88, "order": 88,
@@ -522,7 +514,7 @@
"name": "icon-sine", "name": "icon-sine",
"id": 83, "id": 83,
"code": 921649, "code": 921649,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 102, "order": 102,
@@ -530,7 +522,7 @@
"name": "icon-T", "name": "icon-T",
"id": 84, "id": 84,
"code": 921650, "code": 921650,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 92, "order": 92,
@@ -538,7 +530,7 @@
"name": "icon-thumbs-strip", "name": "icon-thumbs-strip",
"id": 87, "id": 87,
"code": 921651, "code": 921651,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 96, "order": 96,
@@ -546,7 +538,7 @@
"name": "icon-two-parts-both", "name": "icon-two-parts-both",
"id": 91, "id": 91,
"code": 921652, "code": 921652,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 97, "order": 97,
@@ -554,7 +546,7 @@
"name": "icon-two-parts-one-only", "name": "icon-two-parts-one-only",
"id": 92, "id": 92,
"code": 921653, "code": 921653,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 21, "order": 21,
@@ -562,7 +554,7 @@
"name": "icon-resync", "name": "icon-resync",
"id": 16, "id": 16,
"code": 921654, "code": 921654,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 120, "order": 120,
@@ -570,7 +562,7 @@
"name": "icon-reset", "name": "icon-reset",
"prevSize": 24, "prevSize": 24,
"code": 921655, "code": 921655,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 121, "order": 121,
@@ -578,7 +570,7 @@
"name": "icon-x-in-circle", "name": "icon-x-in-circle",
"prevSize": 24, "prevSize": 24,
"code": 921656, "code": 921656,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 118, "order": 118,
@@ -586,7 +578,7 @@
"name": "icon-brightness", "name": "icon-brightness",
"prevSize": 24, "prevSize": 24,
"code": 921657, "code": 921657,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 119, "order": 119,
@@ -594,7 +586,7 @@
"name": "icon-contrast", "name": "icon-contrast",
"prevSize": 24, "prevSize": 24,
"code": 921664, "code": 921664,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 124, "order": 124,
@@ -602,7 +594,7 @@
"name": "icon-expand", "name": "icon-expand",
"prevSize": 24, "prevSize": 24,
"code": 921665, "code": 921665,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 125, "order": 125,
@@ -610,7 +602,7 @@
"name": "icon-list-view", "name": "icon-list-view",
"prevSize": 24, "prevSize": 24,
"code": 921666, "code": 921666,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 133, "order": 133,
@@ -618,7 +610,7 @@
"name": "icon-grid-snap-to", "name": "icon-grid-snap-to",
"prevSize": 24, "prevSize": 24,
"code": 921667, "code": 921667,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 128, "order": 128,
@@ -626,7 +618,7 @@
"name": "icon-grid-snap-no", "name": "icon-grid-snap-no",
"prevSize": 24, "prevSize": 24,
"code": 921668, "code": 921668,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 131, "order": 131,
@@ -634,7 +626,7 @@
"name": "icon-frame-show", "name": "icon-frame-show",
"prevSize": 24, "prevSize": 24,
"code": 921669, "code": 921669,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 130, "order": 130,
@@ -642,7 +634,7 @@
"name": "icon-frame-hide", "name": "icon-frame-hide",
"prevSize": 24, "prevSize": 24,
"code": 921670, "code": 921670,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 138, "order": 138,
@@ -650,7 +642,7 @@
"name": "icon-import", "name": "icon-import",
"prevSize": 24, "prevSize": 24,
"code": 921671, "code": 921671,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 136, "order": 136,
@@ -658,7 +650,7 @@
"name": "icon-export", "name": "icon-export",
"prevSize": 24, "prevSize": 24,
"code": 921672, "code": 921672,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 37, "order": 37,
@@ -666,7 +658,7 @@
"name": "icon-activity", "name": "icon-activity",
"id": 32, "id": 32,
"code": 921856, "code": 921856,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 36, "order": 36,
@@ -674,7 +666,7 @@
"name": "icon-activity-mode", "name": "icon-activity-mode",
"id": 31, "id": 31,
"code": 921857, "code": 921857,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 52, "order": 52,
@@ -682,7 +674,7 @@
"name": "icon-autoflow-tabular", "name": "icon-autoflow-tabular",
"id": 47, "id": 47,
"code": 921858, "code": 921858,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 55, "order": 55,
@@ -690,7 +682,7 @@
"name": "icon-clock", "name": "icon-clock",
"id": 50, "id": 50,
"code": 921859, "code": 921859,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 58, "order": 58,
@@ -698,7 +690,7 @@
"name": "icon-database", "name": "icon-database",
"id": 53, "id": 53,
"code": 921860, "code": 921860,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 57, "order": 57,
@@ -706,7 +698,7 @@
"name": "icon-database-query", "name": "icon-database-query",
"id": 52, "id": 52,
"code": 921861, "code": 921861,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 17, "order": 17,
@@ -714,7 +706,7 @@
"name": "icon-dataset", "name": "icon-dataset",
"id": 12, "id": 12,
"code": 921862, "code": 921862,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 22, "order": 22,
@@ -722,7 +714,7 @@
"name": "icon-datatable", "name": "icon-datatable",
"id": 17, "id": 17,
"code": 921863, "code": 921863,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 59, "order": 59,
@@ -730,7 +722,7 @@
"name": "icon-dictionary", "name": "icon-dictionary",
"id": 54, "id": 54,
"code": 921864, "code": 921864,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 62, "order": 62,
@@ -738,7 +730,7 @@
"name": "icon-folder", "name": "icon-folder",
"id": 57, "id": 57,
"code": 921865, "code": 921865,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 66, "order": 66,
@@ -746,7 +738,7 @@
"name": "icon-image", "name": "icon-image",
"id": 61, "id": 61,
"code": 921872, "code": 921872,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 68, "order": 68,
@@ -754,7 +746,7 @@
"name": "icon-layout", "name": "icon-layout",
"id": 63, "id": 63,
"code": 921873, "code": 921873,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 77, "order": 77,
@@ -762,7 +754,7 @@
"name": "icon-object", "name": "icon-object",
"id": 72, "id": 72,
"code": 921874, "code": 921874,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 78, "order": 78,
@@ -770,7 +762,7 @@
"name": "icon-object-unknown", "name": "icon-object-unknown",
"id": 73, "id": 73,
"code": 921875, "code": 921875,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 79, "order": 79,
@@ -778,7 +770,7 @@
"name": "icon-packet", "name": "icon-packet",
"id": 74, "id": 74,
"code": 921876, "code": 921876,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 80, "order": 80,
@@ -786,7 +778,7 @@
"name": "icon-page", "name": "icon-page",
"id": 75, "id": 75,
"code": 921877, "code": 921877,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 135, "order": 135,
@@ -794,7 +786,7 @@
"name": "icon-plot-overlay", "name": "icon-plot-overlay",
"prevSize": 24, "prevSize": 24,
"code": 921878, "code": 921878,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 113, "order": 113,
@@ -802,7 +794,7 @@
"name": "icon-plot-stacked", "name": "icon-plot-stacked",
"prevSize": 24, "prevSize": 24,
"code": 921879, "code": 921879,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 10, "order": 10,
@@ -810,7 +802,7 @@
"name": "icon-session", "name": "icon-session",
"id": 5, "id": 5,
"code": 921880, "code": 921880,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 24, "order": 24,
@@ -818,7 +810,7 @@
"name": "icon-tabular", "name": "icon-tabular",
"id": 19, "id": 19,
"code": 921881, "code": 921881,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 7, "order": 7,
@@ -826,7 +818,7 @@
"name": "icon-tabular-lad", "name": "icon-tabular-lad",
"id": 2, "id": 2,
"code": 921888, "code": 921888,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 6, "order": 6,
@@ -834,7 +826,7 @@
"name": "icon-tabular-lad-set", "name": "icon-tabular-lad-set",
"id": 1, "id": 1,
"code": 921889, "code": 921889,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 8, "order": 8,
@@ -842,7 +834,7 @@
"name": "icon-tabular-realtime", "name": "icon-tabular-realtime",
"id": 3, "id": 3,
"code": 921890, "code": 921890,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 23, "order": 23,
@@ -850,7 +842,7 @@
"name": "icon-tabular-scrolling", "name": "icon-tabular-scrolling",
"id": 18, "id": 18,
"code": 921891, "code": 921891,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 112, "order": 112,
@@ -858,7 +850,7 @@
"name": "icon-telemetry", "name": "icon-telemetry",
"id": 86, "id": 86,
"code": 921892, "code": 921892,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 90, "order": 90,
@@ -866,7 +858,7 @@
"name": "icon-telemetry-panel", "name": "icon-telemetry-panel",
"id": 85, "id": 85,
"code": 921893, "code": 921893,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 93, "order": 93,
@@ -874,7 +866,7 @@
"name": "icon-timeline", "name": "icon-timeline",
"id": 88, "id": 88,
"code": 921894, "code": 921894,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 116, "order": 116,
@@ -882,7 +874,7 @@
"name": "icon-timer-v1.5", "name": "icon-timer-v1.5",
"prevSize": 24, "prevSize": 24,
"code": 921895, "code": 921895,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 11, "order": 11,
@@ -890,7 +882,7 @@
"name": "icon-topic", "name": "icon-topic",
"id": 6, "id": 6,
"code": 921896, "code": 921896,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 115, "order": 115,
@@ -898,7 +890,7 @@
"name": "icon-box-with-dashed-lines", "name": "icon-box-with-dashed-lines",
"id": 29, "id": 29,
"code": 921897, "code": 921897,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 126, "order": 126,
@@ -906,7 +898,7 @@
"name": "icon-summary-widget", "name": "icon-summary-widget",
"prevSize": 24, "prevSize": 24,
"code": 921904, "code": 921904,
"tempChar": "" "tempChar": ""
}, },
{ {
"order": 139, "order": 139,
@@ -914,7 +906,7 @@
"name": "icon-notebook", "name": "icon-notebook",
"prevSize": 24, "prevSize": 24,
"code": 921905, "code": 921905,
"tempChar": "" "tempChar": ""
} }
], ],
"metadata": { "metadata": {
@@ -1647,26 +1639,6 @@
] ]
} }
}, },
{
"id": 118,
"paths": [
"M962 512l-896 512v-1024z"
],
"attrs": [
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"grid": 16,
"tags": [
"icon-arrow-right-equilateral"
],
"colorPermutations": {
"1161751207457516161751": [
{}
]
}
},
{ {
"paths": [ "paths": [
"M0 512l256 256v-512z", "M0 512l256 256v-512z",
@@ -1966,7 +1938,7 @@
}, },
{ {
"paths": [ "paths": [
"M1024 896l-256.8-256.8c42.4-66.6 65-144 64.8-223.2 0-229.8-186.2-416-416-416s-416 186.2-416 416 186.2 416 416 416c79 0.2 156.4-22.4 223.2-64.8l256.8 256.8 128-128zM212.4 619.6c-112.4-112.4-112.4-294.8 0-407.2s294.8-112.4 407.2 0 112.4 294.8 0 407.2c-54 54-127.2 84.4-203.6 84.4-76.4 0.2-149.8-30.2-203.6-84.4z" "M1024 896l-201.662-201.662c47.922-72.498 73.662-157.434 73.662-246.338 0-119.666-46.6-232.168-131.216-316.784s-197.118-131.216-316.784-131.216-232.168 46.6-316.784 131.216-131.216 197.118-131.216 316.784 46.6 232.168 131.216 316.784 197.118 131.216 316.784 131.216c88.904 0 173.84-25.74 246.338-73.662l201.662 201.662 128-128zM448 704c-141.16 0-256-114.842-256-256 0-141.16 114.84-256 256-256 141.158 0 256 114.84 256 256 0 141.158-114.842 256-256 256z"
], ],
"grid": 16, "grid": 16,
"tags": [ "tags": [
@@ -1974,26 +1946,15 @@
], ],
"defaultCode": 77, "defaultCode": 77,
"id": 68, "id": 68,
"attrs": [ "attrs": [],
{
"fill": "rgb(0, 161, 75)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": { "colorPermutations": {
"1161751207457516161751": [ "1161751207457516161751": []
{
"f": 1
}
]
} }
}, },
{ {
"paths": [ "paths": [
"M1024 896l-256.86-256.86c40.681-62.963 64.861-139.898 64.861-222.481 0-0.232-0-0.464-0.001-0.696l0 0.036c0-229.76-186.24-416-416-416s-416 186.24-416 416 186.24 416 416 416c0.196 0 0.427 0.001 0.659 0.001 82.583 0 159.518-24.18 224.112-65.846l-1.631 0.985 256.86 256.86zM212.36 619.64c-52.114-52.117-84.346-124.114-84.346-203.64 0-159.058 128.942-288 288-288s288 128.942 288 288c0 159.058-128.942 288-288 288-0.005 0-0.010-0-0.014-0l0.001 0c-0.242 0.001-0.529 0.001-0.815 0.001-79.271 0-151.010-32.251-202.811-84.348l-0.013-0.014z", "M640 384h-128v-128h-128v128h-128v128h128v128h128v-128h128z",
"M224 352h384v128h-384v-128z", "M1024 896l-201.662-201.662c47.922-72.498 73.662-157.434 73.662-246.338 0-119.666-46.6-232.168-131.216-316.784s-197.118-131.216-316.784-131.216c-119.666 0-232.168 46.6-316.784 131.216s-131.216 197.118-131.216 316.784c0 119.666 46.6 232.168 131.216 316.784s197.118 131.216 316.784 131.216c88.904 0 173.84-25.74 246.338-73.662l201.662 201.662 128-128zM448 704c-141.16 0-256-114.842-256-256 0-141.16 114.84-256 256-256 141.158 0 256 114.84 256 256 0 141.158-114.842 256-256 256z"
"M352 224h128v384h-128v-384z"
], ],
"grid": 16, "grid": 16,
"tags": [ "tags": [
@@ -2001,37 +1962,15 @@
], ],
"defaultCode": 88, "defaultCode": 88,
"id": 66, "id": 66,
"attrs": [ "attrs": [],
{
"fill": "rgb(0, 161, 75)"
},
{
"fill": "rgb(0, 161, 75)"
},
{
"fill": "rgb(0, 161, 75)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": { "colorPermutations": {
"1161751207457516161751": [ "1161751207457516161751": []
{
"f": 1
},
{
"f": 1
},
{
"f": 1
}
]
} }
}, },
{ {
"paths": [ "paths": [
"M767.2 639.2c42.4-66.6 65-144 64.8-223.2 0-229.8-186.2-416-416-416s-416 186.2-416 416 186.2 416 416 416c79 0.2 156.4-22.4 223.2-64.8l256.8 256.8 128-128-256.8-256.8zM619.6 619.6c-54 54-127.2 84.4-203.6 84.4-76.4 0.2-149.8-30.2-203.6-84.4-112.4-112.4-112.4-294.8 0-407.2s294.8-112.4 407.2 0c112.4 112.4 112.4 294.8 0 407.2z", "M256 384h384v128h-384v-128z",
"M224 352h384v128h-384v-128z" "M1024 896l-201.662-201.662c47.922-72.498 73.662-157.434 73.662-246.338 0-119.666-46.6-232.168-131.216-316.784s-197.118-131.216-316.784-131.216c-119.666 0-232.168 46.6-316.784 131.216s-131.216 197.118-131.216 316.784c0 119.666 46.6 232.168 131.216 316.784s197.118 131.216 316.784 131.216c88.904 0 173.84-25.74 246.338-73.662l201.662 201.662 128-128zM448 704c-141.16 0-256-114.842-256-256 0-141.16 114.84-256 256-256 141.158 0 256 114.84 256 256 0 141.158-114.842 256-256 256z"
], ],
"grid": 16, "grid": 16,
"tags": [ "tags": [
@@ -2039,32 +1978,16 @@
], ],
"defaultCode": 89, "defaultCode": 89,
"id": 67, "id": 67,
"attrs": [ "attrs": [],
{
"fill": "rgb(0, 161, 75)"
},
{
"fill": "rgb(0, 161, 75)"
}
],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": { "colorPermutations": {
"1161751207457516161751": [ "1161751207457516161751": []
{
"f": 1
},
{
"f": 1
}
]
} }
}, },
{ {
"paths": [ "paths": [
"M0 128h1024v128h-1024v-128z", "M0 0h1024v256h-1024v-256z",
"M0 448h1024v128h-1024v-128z", "M0 384h1024v256h-1024v-256z",
"M0 768h1024v128h-1024v-128z" "M0 768h1024v256h-1024v-256z"
], ],
"grid": 16, "grid": 16,
"tags": [ "tags": [
@@ -2072,19 +1995,9 @@
], ],
"defaultCode": 109, "defaultCode": 109,
"id": 69, "id": 69,
"attrs": [ "attrs": [],
{},
{},
{}
],
"isMulticolor": false,
"isMulticolor2": false,
"colorPermutations": { "colorPermutations": {
"1161751207457516161751": [ "1161751207457516161751": []
{},
{},
{}
]
} }
}, },
{ {

View File

@@ -39,7 +39,6 @@
<glyph unicode="&#xe929;" glyph-name="icon-brackets" d="M832 960h-192v-192h191.66l0.34-0.34v-639.32l-0.34-0.34h-191.66v-192h192c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM384 128h-191.66l-0.34 0.34v639.32l0.34 0.34h191.66v192h-192c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h192v192z" /> <glyph unicode="&#xe929;" glyph-name="icon-brackets" d="M832 960h-192v-192h191.66l0.34-0.34v-639.32l-0.34-0.34h-191.66v-192h192c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM384 128h-191.66l-0.34 0.34v639.32l0.34 0.34h191.66v192h-192c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h192v192z" />
<glyph unicode="&#xe930;" glyph-name="icon-crosshair" d="M574 962h-128v-320h128v320zM1022 514h-320v-128h320v128zM574 258h-128v-320h128v320zM318 514h-320v-128h320v128z" /> <glyph unicode="&#xe930;" glyph-name="icon-crosshair" d="M574 962h-128v-320h128v320zM1022 514h-320v-128h320v128zM574 258h-128v-320h128v320zM318 514h-320v-128h320v128z" />
<glyph unicode="&#xe931;" glyph-name="icon-grippy-v2" horiz-adv-x="586" d="M146.4 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 886.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 667.4c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 448c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 228.6c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 9.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2z" /> <glyph unicode="&#xe931;" glyph-name="icon-grippy-v2" horiz-adv-x="586" d="M146.4 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM146.4 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 886.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 667.4c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 448c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 228.6c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM365.8 9.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 777.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 557.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 338.2c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2zM585.2 118.8c0-40.427-32.773-73.2-73.2-73.2s-73.2 32.773-73.2 73.2c0 40.427 32.773 73.2 73.2 73.2s73.2-32.773 73.2-73.2z" />
<glyph unicode="&#xe932;" glyph-name="icon-arrow-right-equilateral" d="M962 448l-896-512v1024z" />
<glyph unicode="&#xe1000;" glyph-name="icon-arrows-out" d="M0 448l256-256v512zM512 960l-256-256h512zM512-64l256 256h-512zM768 704v-512l256 256z" /> <glyph unicode="&#xe1000;" glyph-name="icon-arrows-out" d="M0 448l256-256v512zM512 960l-256-256h512zM512-64l256 256h-512zM768 704v-512l256 256z" />
<glyph unicode="&#xe1001;" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" /> <glyph unicode="&#xe1001;" glyph-name="icon-arrows-right-left" d="M1024 448l-448-512v1024zM448 960l-448-512 448-512z" />
<glyph unicode="&#xe1002;" glyph-name="icon-arrows-up-down" d="M512 960l512-448h-1024zM0 384l512-448 512 448z" /> <glyph unicode="&#xe1002;" glyph-name="icon-arrows-up-down" d="M512 960l512-448h-1024zM0 384l512-448 512 448z" />
@@ -55,10 +54,10 @@
<glyph unicode="&#xe1013;" glyph-name="icon-fullscreen-collapse" d="M191.656 128c0.118-0.1 0.244-0.224 0.344-0.344v-191.656h192v192c0 105.6-86.4 192-192 192h-192v-192h191.656zM192 768.344c-0.1-0.118-0.224-0.244-0.344-0.344h-191.656v-192h192c105.6 0 192 86.4 192 192v192h-192v-191.656zM832 576h192v192h-191.656c-0.118 0.1-0.244 0.226-0.344 0.344v191.656h-192v-192c0-105.6 86.4-192 192-192zM832 127.656c0.1 0.118 0.224 0.244 0.344 0.344h191.656v192h-192c-105.6 0-192-86.4-192-192v-192h192v191.656z" /> <glyph unicode="&#xe1013;" glyph-name="icon-fullscreen-collapse" d="M191.656 128c0.118-0.1 0.244-0.224 0.344-0.344v-191.656h192v192c0 105.6-86.4 192-192 192h-192v-192h191.656zM192 768.344c-0.1-0.118-0.224-0.244-0.344-0.344h-191.656v-192h192c105.6 0 192 86.4 192 192v192h-192v-191.656zM832 576h192v192h-191.656c-0.118 0.1-0.244 0.226-0.344 0.344v191.656h-192v-192c0-105.6 86.4-192 192-192zM832 127.656c0.1 0.118 0.224 0.244 0.344 0.344h191.656v192h-192c-105.6 0-192-86.4-192-192v-192h192v191.656z" />
<glyph unicode="&#xe1014;" glyph-name="icon-layers" d="M1024 576l-512 384-512-384 512-384zM512 64l-426.666 320-85.334-64 512-384 512 384-85.334 64z" /> <glyph unicode="&#xe1014;" glyph-name="icon-layers" d="M1024 576l-512 384-512-384 512-384zM512 64l-426.666 320-85.334-64 512-384 512 384-85.334 64z" />
<glyph unicode="&#xe1015;" glyph-name="icon-line-horz" d="M64 384c-35.346 0-64 28.654-64 64s28.654 64 64 64h896c35.346 0 64-28.654 64-64s-28.654-64-64-64h-896z" /> <glyph unicode="&#xe1015;" glyph-name="icon-line-horz" d="M64 384c-35.346 0-64 28.654-64 64s28.654 64 64 64h896c35.346 0 64-28.654 64-64s-28.654-64-64-64h-896z" />
<glyph unicode="&#xe1016;" glyph-name="icon-magnify" d="M1024 64l-256.8 256.8c42.4 66.6 65 144 64.8 223.2 0 229.8-186.2 416-416 416s-416-186.2-416-416 186.2-416 416-416c79-0.2 156.4 22.4 223.2 64.8l256.8-256.8 128 128zM212.4 340.4c-112.4 112.4-112.4 294.8 0 407.2s294.8 112.4 407.2 0 112.4-294.8 0-407.2c-54-54-127.2-84.4-203.6-84.4-76.4-0.2-149.8 30.2-203.6 84.4z" /> <glyph unicode="&#xe1016;" glyph-name="icon-magnify" d="M1024 64l-201.662 201.662c47.922 72.498 73.662 157.434 73.662 246.338 0 119.666-46.6 232.168-131.216 316.784s-197.118 131.216-316.784 131.216-232.168-46.6-316.784-131.216-131.216-197.118-131.216-316.784 46.6-232.168 131.216-316.784 197.118-131.216 316.784-131.216c88.904 0 173.84 25.74 246.338 73.662l201.662-201.662 128 128zM448 256c-141.16 0-256 114.842-256 256 0 141.16 114.84 256 256 256 141.158 0 256-114.84 256-256 0-141.158-114.842-256-256-256z" />
<glyph unicode="&#xe1017;" glyph-name="icon-magnify-in" d="M1024 64l-256.86 256.86c40.681 62.963 64.861 139.898 64.861 222.481 0 0.232 0 0.464-0.001 0.696v-0.036c0 229.76-186.24 416-416 416s-416-186.24-416-416 186.24-416 416-416c0.196 0 0.427-0.001 0.659-0.001 82.583 0 159.518 24.18 224.112 65.846l-1.631-0.985 256.86-256.86zM212.36 340.36c-52.114 52.117-84.346 124.114-84.346 203.64 0 159.058 128.942 288 288 288s288-128.942 288-288c0-159.058-128.942-288-288-288-0.005 0-0.010 0-0.014 0h0.001c-0.242-0.001-0.529-0.001-0.815-0.001-79.271 0-151.010 32.251-202.811 84.348l-0.013 0.014zM224 608h384v-128h-384v128zM352 736h128v-384h-128v384z" /> <glyph unicode="&#xe1017;" glyph-name="icon-magnify-in" d="M640 576h-128v128h-128v-128h-128v-128h128v-128h128v128h128zM1024 64l-201.662 201.662c47.922 72.498 73.662 157.434 73.662 246.338 0 119.666-46.6 232.168-131.216 316.784s-197.118 131.216-316.784 131.216c-119.666 0-232.168-46.6-316.784-131.216s-131.216-197.118-131.216-316.784c0-119.666 46.6-232.168 131.216-316.784s197.118-131.216 316.784-131.216c88.904 0 173.84 25.74 246.338 73.662l201.662-201.662 128 128zM448 256c-141.16 0-256 114.842-256 256 0 141.16 114.84 256 256 256 141.158 0 256-114.84 256-256 0-141.158-114.842-256-256-256z" />
<glyph unicode="&#xe1018;" glyph-name="icon-magnify-out" d="M767.2 320.8c42.4 66.6 65 144 64.8 223.2 0 229.8-186.2 416-416 416s-416-186.2-416-416 186.2-416 416-416c79-0.2 156.4 22.4 223.2 64.8l256.8-256.8 128 128-256.8 256.8zM619.6 340.4c-54-54-127.2-84.4-203.6-84.4-76.4-0.2-149.8 30.2-203.6 84.4-112.4 112.4-112.4 294.8 0 407.2s294.8 112.4 407.2 0c112.4-112.4 112.4-294.8 0-407.2zM224 608h384v-128h-384v128z" /> <glyph unicode="&#xe1018;" glyph-name="icon-magnify-out" d="M256 576h384v-128h-384v128zM1024 64l-201.662 201.662c47.922 72.498 73.662 157.434 73.662 246.338 0 119.666-46.6 232.168-131.216 316.784s-197.118 131.216-316.784 131.216c-119.666 0-232.168-46.6-316.784-131.216s-131.216-197.118-131.216-316.784c0-119.666 46.6-232.168 131.216-316.784s197.118-131.216 316.784-131.216c88.904 0 173.84 25.74 246.338 73.662l201.662-201.662 128 128zM448 256c-141.16 0-256 114.842-256 256 0 141.16 114.84 256 256 256 141.158 0 256-114.84 256-256 0-141.158-114.842-256-256-256z" />
<glyph unicode="&#xe1019;" glyph-name="icon-menu" d="M0 832h1024v-128h-1024v128zM0 512h1024v-128h-1024v128zM0 192h1024v-128h-1024v128z" /> <glyph unicode="&#xe1019;" glyph-name="icon-menu" d="M0 960h1024v-256h-1024v256zM0 576h1024v-256h-1024v256zM0 192h1024v-256h-1024v256z" />
<glyph unicode="&#xe1020;" glyph-name="icon-move" d="M293.4 448l218.6 218.6 256-256v421.4c0 70.4-57.6 128-128 128h-512c-70.4 0-128-57.6-128-128v-512c0-70.4 57.6-128 128-128h421.4l-256 256zM1024 512h-128v-320l-384 384-128-128 384-384h-320v-128h576z" /> <glyph unicode="&#xe1020;" glyph-name="icon-move" d="M293.4 448l218.6 218.6 256-256v421.4c0 70.4-57.6 128-128 128h-512c-70.4 0-128-57.6-128-128v-512c0-70.4 57.6-128 128-128h421.4l-256 256zM1024 512h-128v-320l-384 384-128-128 384-384h-320v-128h576z" />
<glyph unicode="&#xe1021;" glyph-name="icon-new-window" d="M448 960v-128h320l-384-384 128-128 384 384v-320h128v576zM576 285.726v-157.382c-0.1-0.118-0.226-0.244-0.344-0.344h-383.312c-0.118 0.1-0.244 0.226-0.344 0.344v383.312c0.1 0.118 0.226 0.244 0.344 0.344h157.382l192 192h-349.726c-105.6 0-192-86.4-192-192v-384c0-105.6 86.4-192 192-192h384c105.6 0 192 86.4 192 192v349.726l-192-192z" /> <glyph unicode="&#xe1021;" glyph-name="icon-new-window" d="M448 960v-128h320l-384-384 128-128 384 384v-320h128v576zM576 285.726v-157.382c-0.1-0.118-0.226-0.244-0.344-0.344h-383.312c-0.118 0.1-0.244 0.226-0.344 0.344v383.312c0.1 0.118 0.226 0.244 0.344 0.344h157.382l192 192h-349.726c-105.6 0-192-86.4-192-192v-384c0-105.6 86.4-192 192-192h384c105.6 0 192 86.4 192 192v349.726l-192-192z" />
<glyph unicode="&#xe1022;" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" /> <glyph unicode="&#xe1022;" glyph-name="icon-paint-bucket" d="M544 736v-224c0-88.4-71.6-160-160-160s-160 71.6-160 160v97.2l-197.4-196.4c-50-50-12.4-215.2 112.4-340s290-162.4 340-112.4l417 423.6-352 352zM896-64c70.6 0 128 57.4 128 128 0 108.6-128 192-128 192s-128-83.4-128-192c0-70.6 57.4-128 128-128zM384 448c-35.4 0-64 28.6-64 64v384c0 35.4 28.6 64 64 64s64-28.6 64-64v-384c0-35.4-28.6-64-64-64z" />

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -157,57 +157,3 @@
.t-popup { .t-popup {
z-index: 75; z-index: 75;
} }
/********************************************* GRID STYLES */
.grid-two-column {
display: grid;
grid-row-gap: 0;
grid-template-columns: 1fr 2fr;
align-items: top;
}
.grid-two-column-span-cols {
grid-column: 1 / 3;
}
.grid-elem {
&:not(:first-child) {
border-top: 1px solid $colorInteriorBorder;
}
&.label {
background-color: rgba(0,0,128,0.2);
}
&.value {
background-color: rgba(0,128,0,0.2);
}
}
// Properties grids
.grid-properties {
@extend .grid-two-column;
}
.grid-row {
display: contents;
}
.grid-span-all {
@extend .grid-two-column-span-cols;
}
.grid-row {
.grid-cell {
padding: 3px $interiorMarginLg 3px 0;
&[title] {
// When a cell has a title, assume it's helpful text
cursor: help;
}
}
&.force-border,
&:not(:first-of-type) {
// Row borders, effected via border-top on child elements of the row
.grid-cell {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
}

View File

@@ -37,9 +37,25 @@
vertical-align: middle; vertical-align: middle;
} }
//.top-bar .btn-browse .badge {
// Moved to _controls.scss .btn.browse-btn
// border-radius: $controlCr * 1.5;
// $d: 20px;
// display: block;
// font-size: 1em;
// line-height: $d;
//// margin-top: -4px;
//
// position: absolute;
// top: 5px; left: 5px; bottom: 5px; right: auto;
// width: $d; height: auto;
//}
.super-menu .badge { .super-menu .badge {
@include background-image(linear-gradient(lighten($colorCreateBtn, 10%), $colorCreateBtn)); @include background-image(linear-gradient(lighten($colorCreateBtn, 10%), $colorCreateBtn));
border-radius: $controlCr; border-radius: $controlCr;
@include boxShdwSubtle(); @include boxShdwSubtle();
// display: inline-block;
// margin-right: 10px !important;
padding: 2px 7px; padding: 2px 7px;
} }

View File

@@ -43,10 +43,10 @@ $ueColMargin: 1.5%;
$ueAppLogoW: 80px; $ueAppLogoW: 80px;
$ueEditToolBarH: 25px; $ueEditToolBarH: 25px;
$ueCollapsedPaneEdgeM: 22px; $ueCollapsedPaneEdgeM: 22px;
$uePaneMiniTabH: 36px; $uePaneMiniTabH: 22px;
$uePaneMiniTabW: 10px; $uePaneMiniTabW: 8px;
$uePaneMiniTabFontSize: 9px; $uePaneMiniTabFontSize: 8px;
$uePaneMiniTabCollapsedW: 22px; $uePaneMiniTabCollapsedW: 18px;
$ueEditLeftPaneW: 75%; $ueEditLeftPaneW: 75%;
$treeSearchInputBarH: 25px; $treeSearchInputBarH: 25px;
/*************** Panes */ /*************** Panes */
@@ -70,7 +70,7 @@ $ueBrowseGridItemTopBarH: 20px;
$ueBrowseGridItemBottomBarH: 30px; $ueBrowseGridItemBottomBarH: 30px;
$itemPadLR: 5px; $itemPadLR: 5px;
/*************** Tree */ /*************** Tree */
$treeVCW: 16px; $treeVCW: 10px;
$treeTypeIconH: 1.4em; // was 16px $treeTypeIconH: 1.4em; // was 16px
$treeTypeIconHPx: 16px; $treeTypeIconHPx: 16px;
$treeTypeIconW: 18px; $treeTypeIconW: 18px;
@@ -111,7 +111,7 @@ $bubbleMaxW: 300px;
$reqSymbolW: 15px; $reqSymbolW: 15px;
$reqSymbolM: $interiorMargin * 2; $reqSymbolM: $interiorMargin * 2;
$reqSymbolFontSize: 0.75em; $reqSymbolFontSize: 0.75em;
$inputTextPTopBtm: 2px; $inputTextPTopBtm: 3px;
$inputTextPLeftRight: 5px; $inputTextPLeftRight: 5px;
$inputTextP: $inputTextPTopBtm $inputTextPLeftRight; $inputTextP: $inputTextPTopBtm $inputTextPLeftRight;
/*************** Wait Spinner Defaults */ /*************** Wait Spinner Defaults */
@@ -132,7 +132,7 @@ $menuLineHPx: 24px;
$btnStdH: 25px; $btnStdH: 25px;
$btnToolbarH: $btnStdH; $btnToolbarH: $btnStdH;
$controlBarH: $btnStdH; $controlBarH: $btnStdH;
$btnFrameH: 18px; $btnFrameH: 16px;
/************************** PATHS */ /************************** PATHS */
// Paths need to be relative to /platform/commonUI/theme/<theme-name>/css/ directory // Paths need to be relative to /platform/commonUI/theme/<theme-name>/css/ directory

View File

@@ -141,6 +141,7 @@ a.disabled {
.s-status-missing { .s-status-missing {
// Labels. Expects .s-status-missing to be applied to mct-representation that contains // Labels. Expects .s-status-missing to be applied to mct-representation that contains
// .t-object-label
.t-object-label .t-item-icon:before { .t-object-label .t-item-icon:before {
content: $glyph-icon-object-unknown; content: $glyph-icon-object-unknown;
} }
@@ -199,16 +200,7 @@ a.disabled {
} }
.vscroll { .vscroll {
overflow-x: hidden;
overflow-y: auto; overflow-y: auto;
&.scroll-pad {
padding-right: $interiorMargin;
}
}
.vscroll--persist {
overflow-x: hidden;
overflow-y: scroll;
} }
.slidable { .slidable {
@@ -232,13 +224,8 @@ a.disabled {
box-shadow: rgba(#000, 0.7) 0 4px 10px 2px; box-shadow: rgba(#000, 0.7) 0 4px 10px 2px;
} }
.capitalize {
text-transform: capitalize;
}
.hide, .hide,
.hidden, .hidden {
.t-main-view .hide-in-t-main-view {
display: none !important; display: none !important;
} }
@@ -247,16 +234,14 @@ a.disabled {
pointer-events: none; pointer-events: none;
} }
.invisible { .off {
display: block;
visibility: hidden; visibility: hidden;
opacity: 0;
height: 0; height: 0;
margin: 0;
padding: 0; padding: 0;
border: 0; border: 0;
margin: 0 !important; margin: 0 !important;
transform: scale(0);
pointer-events: none;
position: absolute;
} }
.sep { .sep {

View File

@@ -33,14 +33,6 @@
} }
} }
[class*="icon-"].labeled {
// Moved from .s-button and generalized
&:before {
// Fend off label from icon when it's included
margin-right: $interiorMarginSm;
}
}
/************************** CHAR UNICODES */ /************************** CHAR UNICODES */
$glyph-icon-alert-rect: '\e900'; $glyph-icon-alert-rect: '\e900';
@@ -75,7 +67,6 @@ $glyph-icon-x: '\e928';
$glyph-icon-brackets: '\e929'; $glyph-icon-brackets: '\e929';
$glyph-icon-crosshair: '\e930'; $glyph-icon-crosshair: '\e930';
$glyph-icon-grippy: '\e931'; $glyph-icon-grippy: '\e931';
$glyph-icon-arrow-right-equilateral: '\e932';
$glyph-icon-arrows-out: '\e1000'; $glyph-icon-arrows-out: '\e1000';
$glyph-icon-arrows-right-left: '\e1001'; $glyph-icon-arrows-right-left: '\e1001';
$glyph-icon-arrows-up-down: '\e1002'; $glyph-icon-arrows-up-down: '\e1002';
@@ -191,7 +182,6 @@ $glyph-icon-notebook: '\e1131';
.icon-brackets { @include glyphBefore($glyph-icon-brackets); } .icon-brackets { @include glyphBefore($glyph-icon-brackets); }
.icon-crosshair { @include glyphBefore($glyph-icon-crosshair); } .icon-crosshair { @include glyphBefore($glyph-icon-crosshair); }
.icon-grippy { @include glyphBefore($glyph-icon-grippy); } .icon-grippy { @include glyphBefore($glyph-icon-grippy); }
.icon-arrow-right-equilateral { @include glyphBefore($glyph-icon-arrow-right-equilateral); }
.icon-arrows-out { @include glyphBefore($glyph-icon-arrows-out); } .icon-arrows-out { @include glyphBefore($glyph-icon-arrows-out); }
.icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); } .icon-arrows-right-left { @include glyphBefore($glyph-icon-arrows-right-left); }
.icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); } .icon-arrows-up-down { @include glyphBefore($glyph-icon-arrows-up-down); }

View File

@@ -19,15 +19,23 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/* Styles for the Inspector pane */
.l-inspect,
.l-inspect table tr td {
font-size: 0.75rem;
}
/* New grid layout for the Inspector pane */
.l-inspect { .l-inspect {
// Overall layout
@extend .abs; @extend .abs;
background: $colorInspectorBg; background: $colorInspectorBg;
color: $colorInspectorFg; color: $colorInspectorFg;
line-height: 140%; line-height: 140%;
.flex-elem.holder:not(:last-child) {
margin-bottom: $interiorMargin;
}
.pane-header { .pane-header {
color: pushBack($colorInspectorFg, 20%); color: pushBack($colorInspectorFg, 20%);
font-size: 0.8rem; font-size: 0.8rem;
@@ -42,48 +50,80 @@
} }
} }
} }
.l-inspector-part { .l-inspector-part {
display: contents; box-sizing: border-box;
} padding-right: $interiorMargin;
.tree .form {
.tree {
.grid-properties {
margin-left: $treeVCW + $interiorMarginLg; margin-left: $treeVCW + $interiorMarginLg;
} }
} .section-header {
background: none;
.grid-properties {
.label {
color: $colorInspectorPropName; color: $colorInspectorPropName;
border-radius: unset;
font-size: inherit;
padding: $interiorMarginSm 0;
} }
.value {
color: $colorInspectorPropVal; mct-form:not(:last-child) .form {
word-break: break-all; border-bottom: 1px solid $colorInspectorSectionHeaderBg;
&:first-child { }
// If there is no preceding .label element, make value span columns
@extend .grid-two-column-span-cols; .form {
margin-bottom: $interiorMarginSm;
padding-bottom: $interiorMarginLg;
.l-section-body {
margin-bottom: 0;
&:not(.first) {
border-top: 1px solid $colorFormLines;
}
}
.form-row {
align-items: center;
border: none !important;
margin-bottom: 0 !important;
padding: $interiorMarginSm 0;
.label {
min-width: 80px;
}
input[type='text'],
input[type='search'] {
width: 100%;
}
} }
} }
} }
.inspector-location { ul li,
display: inline-block; em.t-inspector-part-header {
display: block;
position: relative;
} }
h2 { ul li {
// Headers for .l-inspector-part elements margin-bottom: $interiorMarginLg;
@extend .grid-two-column-span-cols; }
border-radius: $controlCr;
em.t-inspector-part-header {
border-radius: $basicCr;
background-color: $colorInspectorSectionHeaderBg; background-color: $colorInspectorSectionHeaderBg;
color: $colorInspectorSectionHeaderFg; color: $colorInspectorSectionHeaderFg;
font-size: 0.8rem; margin-bottom: $interiorMargin;
font-weight: normal;
margin: $interiorMarginLg 0 $interiorMarginSm 0;
padding: floor($formTBPad * .75) $formLRPad; padding: floor($formTBPad * .75) $formLRPad;
text-transform: uppercase; text-transform: uppercase;
&.first { }
margin-top: 0;
.inspector-properties {
&:not(.first) {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
padding: $interiorMarginSm 0;
.label {
color: $colorInspectorPropName;
text-transform: uppercase;
}
.value {
color: $colorInspectorPropVal;
word-break: break-all;
} }
} }
@@ -122,34 +162,6 @@
width: 4px; width: 4px;
} }
} }
// Elements pool
.holder-elements {
.current-elements {
position: relative;
.tree-item {
.t-object-label {
// Elements pool is a flat list, so don't indent items.
font-size: 0.75rem;
left: 0;
}
}
}
}
}
/* Styles for the Inspector pane */
.l-inspect,
.l-inspect table tr td {
font-size: 0.75rem;
}
.l-inspect {
.flex-elem.holder:not(:last-child) {
margin-bottom: $interiorMargin;
}
.holder-elements { .holder-elements {
.current-elements { .current-elements {
position: relative; position: relative;

View File

@@ -42,7 +42,6 @@
@import "controls/lists"; @import "controls/lists";
@import "controls/menus"; @import "controls/menus";
@import "controls/messages"; @import "controls/messages";
@import "controls/indicators";
@import "mobile/controls/menus"; @import "mobile/controls/menus";
/********************************* FORMS */ /********************************* FORMS */

View File

@@ -299,7 +299,7 @@
color: $ic; color: $ic;
} }
@if $bgHov != none { @if $bgHov != none {
&:not([disabled="true"]):not(.disabled):hover { &:not(.disabled):hover {
background: $bgHov; background: $bgHov;
color: $fgHov; color: $fgHov;
>.icon, >.icon,
@@ -334,7 +334,7 @@
color: $fg; color: $fg;
} }
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.5) 0 0px 2px) { @mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.6) 0 1px 3px) {
@include s-input($bg, $fg, $shdw); @include s-input($bg, $fg, $shdw);
border: none; border: none;
outline: none; outline: none;

View File

@@ -20,120 +20,66 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*************************************************** MIXINS */ /*************************************************** MIXINS */
@mixin elementStatusColors($c) { @mixin formulateStatusColors($c) {
// Sets bg and icon colors for elements // Sets bg and icon colors for elements
background: rgba($c, 0.5) !important; background: rgba($c, 0.4) !important;
&:before { &:before { color: $c !important; }
color: $c !important;
}
} }
@mixin indicatorStatusColors($c) {
&:before, .count {
color: $c;
}
}
/*************************************************** GENERAL */ /*************************************************** GENERAL */
.s-limit-upr, .s-limit-yellow,
.s-limit-lwr, .s-limit-red,
[class*='s-limit-icon'], .s-limit-yellow-icon,
[class*='s-status-icon'] { .s-limit-red-icon,
.s-status-warning-lo,
.s-status-warning-hi,
.s-status-diagnostic,
.s-status-command,
.s-status-info,
.s-status-ok,
.s-status-warning-lo-icon,
.s-status-warning-hi-icon,
.s-status-diagnostic-icon,
.s-status-command-icon,
.s-status-info-icon,
.s-status-ok-icon {
@include trans-prop-nice($props: background, $dur: 500ms);
&:before { &:before {
content:''; content:'';
display: inline-block;
font-family: symbolsfont; font-family: symbolsfont;
font-size: 0.8em; font-size: 0.8em;
margin-right: $interiorMarginSm;
} }
} }
/*************************************************** LIMITS */ /*************************************************** LIMITS */
[class*='s-limit'] { .s-limit-yellow, .s-limit-yellow-icon {
&[class*='icon-'] { @include formulateStatusColors($colorWarningLo);
&:before {
margin-right: $interiorMargin;
}
}
} }
.s-limit-yellow, .s-limit-icon-yellow { .s-limit-red, .s-limit-red-icon {
@include elementStatusColors($colorWarningLo); @include formulateStatusColors($colorWarningHi);
} }
.s-limit-red, .s-limit-icon-red { .s-limit-upr:before { content: $glyph-icon-arrow-double-up; }
@include elementStatusColors($colorWarningHi); .s-limit-lwr:before { content: $glyph-icon-arrow-double-down; }
} .s-limit-yellow-icon:before,
.s-limit-red-icon:before { content: $glyph-icon-alert-triangle; }
.s-limit {
&-upr,
&-lwr {
&:before {
margin-right: $interiorMargin;
}
}
&-upr:before { content: $glyph-icon-arrow-double-up; }
&-lwr:before { content: $glyph-icon-arrow-double-down; }
&-icon-yellow,
&-icon-red {
&:before {
content: $glyph-icon-alert-triangle;
}
}
}
/*************************************************** STATUS */ /*************************************************** STATUS */
[class*='s-status'] { .s-status-warning-hi, .s-status-warning-hi-icon { @include formulateStatusColors($colorWarningHi); }
&[class*='icon-'] { .s-status-warning-lo, .s-status-warning-lo-icon { @include formulateStatusColors($colorWarningLo); }
&:before { .s-status-diagnostic, .s-status-diagnostic-icon { @include formulateStatusColors($colorDiagnostic); }
margin-right: $interiorMargin; .s-status-info, .s-status-info-icon { @include formulateStatusColors($colorInfo); }
} .s-status-ok, .s-status-ok-icon { @include formulateStatusColors($colorOk); }
}
}
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); } .s-status-warning-hi-icon:before { content: $glyph-icon-alert-triangle; }
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); } .s-status-warning-lo-icon:before { content: $glyph-icon-alert-rect; }
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); } .s-status-diagnostic-icon:before { content: $glyph-icon-eye-open; }
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); } .s-status-info-icon:before { content: $glyph-icon-info; }
.s-status-ok, .s-status-icon-ok { @include elementStatusColors($colorOk); } .s-status-ok-icon:before { content: $glyph-icon-check; }
.s-status-icon-warning-hi:before { content: $glyph-icon-alert-triangle; }
.s-status-icon-warning-lo:before { content: $glyph-icon-alert-rect; }
.s-status-icon-diagnostic:before { content: $glyph-icon-eye-open; }
.s-status-icon-info:before { content: $glyph-icon-info; }
.s-status-icon-ok:before { content: $glyph-icon-check; }
/*************************************************** INDICATOR COLORING */
.ls-indicator {
&.s-status-info {
@include indicatorStatusColors($colorInfo);
}
&.s-status-disabled {
@include indicatorStatusColors($colorIndicatorDisabled);
}
&.s-status-available {
@include indicatorStatusColors($colorIndicatorAvailable);
}
&.s-status-on,
&.s-status-enabled {
@include indicatorStatusColors($colorIndicatorOn);
}
&.s-status-off {
@include indicatorStatusColors($colorIndicatorOff);
}
&.s-status-caution,
&.s-status-warning,
&.s-status-alert {
@include indicatorStatusColors($colorStatusAlert);
}
&.s-status-error {
@include indicatorStatusColors($colorStatusError);
}
}

View File

@@ -271,3 +271,36 @@
@extend .l-summary-widget; @extend .l-summary-widget;
padding: $interiorMarginSm $interiorMargin; padding: $interiorMarginSm $interiorMargin;
} }
// Hide and show elements in the rule-header on hover
.l-widget-rule,
.l-widget-test-data-item {
.grippy,
.l-rule-action-buttons-wrapper,
.l-condition-action-buttons-wrapper,
.l-widget-test-data-item-action-buttons-wrapper {
@include trans-prop-nice($props: opacity, $dur: 500ms);
opacity: 0;
}
&:hover {
.grippy,
.l-rule-action-buttons-wrapper,
.l-widget-test-data-item-action-buttons-wrapper {
@include trans-prop-nice($props: opacity, $dur: 0);
opacity: 1;
}
}
.l-rule-action-buttons-wrapper {
.t-delete {
margin-left: 10px;
}
}
.t-condition {
&:hover {
.l-condition-action-buttons-wrapper {
@include trans-prop-nice($props: opacity, $dur: 0);
opacity: 1;
}
}
}
}

View File

@@ -34,6 +34,11 @@ $pad: $interiorMargin * $baseRatio;
line-height: $btnStdH; line-height: $btnStdH;
padding: 0 $pad; padding: 0 $pad;
&.labeled:before {
// Icon when it's included
margin-right: $interiorMarginSm;
}
&.lg { &.lg {
font-size: 1rem; font-size: 1rem;
} }
@@ -54,10 +59,6 @@ $pad: $interiorMargin * $baseRatio;
.label, .title-label { display: none; } .label, .title-label { display: none; }
} }
&[disabled="true"] {
opacity: 0.3;
}
&.pause-play { &.pause-play {
@extend .icon-pause; @extend .icon-pause;
&.paused { &.paused {
@@ -113,11 +114,10 @@ body.desktop .mini-tab-icon {
.l-btn-set { .l-btn-set {
// Buttons that have a very tight conceptual grouping - no internal space between them. // Buttons that have a very tight conceptual grouping - no internal space between them.
font-size: 0; // Remove space between s-button elements due to white space in markup font-size: 0; // Remove space between s-button elements due to white space in markup
white-space: nowrap;
.s-button { .s-button {
border-radius: 0; border-radius: 0;
margin-left: 1px !important; margin-left: 1px;
} }
> .s-button { > .s-button {

View File

@@ -128,70 +128,26 @@
} }
} }
.l-local-controls {
// Control shown when hovering over an object, like plots and imagery
/******************************************************** LOCAL CONTROLS */ // Default position is upper right
// Controls placed in proximity to or overlaid on components and views $p: $interiorMargin;
position: absolute;
.local-controls-hidden { top: $p; right: $p; bottom: auto;
// Used within .has-local-controls, hidden by default text-align: right;
z-index: 5;
} }
body.desktop .has-local-controls { .s-local-controls {
// Helper class, provides hover ability to show local controls @include trans-prop-nice(opacity);
&:hover .local-controls-hidden {
@include trans-prop-nice($props: opacity, $dur: 50ms);
opacity: 1;
pointer-events: inherit;
}
.local-controls-hidden {
@include trans-prop-nice($props: opacity, $dur: 500ms);
opacity: 0;
pointer-events: none;
}
}
.h-local-controls {
// An explicit outer holder for controls. Typically placed in upper right.
align-items: center;
font-size: 0.7rem; font-size: 0.7rem;
display: flex; &.s-wrapper-transluc {
flex-direction: row; // Semi-opaque wrapper to visually distinguish a control
justify-content: flex-end; // from the background
background: rgba($colorTransLucBg, 0.7);
box-sizing: border-box;
&.h-local-controls-overlay-content { border-radius: $controlCr;
$p: $interiorMargin;
position: absolute;
top: $p; right: $p;
z-index: 2;
} }
.l-btn-set,
.s-button {
&:not(:first-child) {
margin-left: $interiorMargin;
}
}
}
.h-local-controls-overlay-content {
background: $colorBodyBg;
border-radius: $controlCr + 1;
box-sizing: border-box;
border-radius: $controlCr;
padding: 1px;
.s-button {
background: $colorBtnBg;
}
}
.h-local-controls-trans {
background: rgba($colorTransLucBg, 0.5);
padding: $interiorMargin;
} }
/******************************************************** VIEW CONTROLS */ /******************************************************** VIEW CONTROLS */
@@ -203,11 +159,10 @@ body.desktop .has-local-controls {
cursor: pointer; cursor: pointer;
height: 1em; width: 1em; height: 1em; width: 1em;
line-height: inherit; line-height: inherit;
position: relative;
&:before { &:before {
position: absolute; position: absolute;
@include trans-prop-nice(transform, 100ms); @include trans-prop-nice(transform, 100ms);
content: $glyph-icon-arrow-right-equilateral; content: $glyph-icon-arrow-right;
@include transform-origin(center); @include transform-origin(center);
} }
&.expanded:before { &.expanded:before {
@@ -383,7 +338,6 @@ input[type="text"].s-input-inline,
@include btnSubtle($bg: $colorSelectBg); @include btnSubtle($bg: $colorSelectBg);
@extend .icon-arrow-down; // Context arrow @extend .icon-arrow-down; // Context arrow
display: inline-block; display: inline-block;
flex: 0 0 auto; // When used in a flex context, controls need to hold their width
padding: 0 $interiorMargin; padding: 0 $interiorMargin;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@@ -806,17 +760,13 @@ textarea {
@extend .icon-arrow-right; @extend .icon-arrow-right;
cursor: pointer; cursor: pointer;
font-size: 0.75em; font-size: 0.75em;
width: $treeVCW;
&:before { &:before {
// Arrow glyph
left: 50%;
position: absolute; position: absolute;
@include trans-prop-nice(transform, 100ms); @include trans-prop-nice(transform, 100ms);
transform: translateX(-50%);
transform-origin: center; transform-origin: center;
} }
&.expanded:before { &.expanded:before {
transform: translateX(-50%) rotate(90deg); transform: rotate(90deg);
} }
} }

View File

@@ -1,147 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/* Indicators are generally only displayed in the ue-bottom-bar element of the main interface */
.h-indicator,
mct-indicators mct-include {
display: inline; // Fallback for display: contents
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
&:before {
display: inline-block;
}
.label {
display: inline-block;
a,
button,
.s-button {
// Make <a> in label look like buttons
@include trans-prop-nice($props: all, $dur: 100ms);
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;
}
}
button { text-transform: uppercase !important; }
}
&.no-collapse {
display: flex;
flex-flow: row nowrap;
align-items: center;
> *,
&:before {
flex: 1 1 auto;
}
&:before {
margin-right: $interiorMarginSm;
}
}
&:not(.no-collapse) {
z-index: 0;
&: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;
&:before {
// Infobubble-style arrow element
content: '';
display: block;
position: absolute;
top: 100%;
@include triangle('down', $size: 4px, $ratio: 1, $color: $hbg);
}
}
&:hover {
background: $bg;
z-index: 1;
.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;
}
}

View File

@@ -19,9 +19,9 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/******************************************************************* STATUS BLOCK ELEMS */
@mixin statusBannerColors($bg, $fg: $colorStatusFg) { @mixin statusBannerColors($bg, $fg: $colorStatusFg) {
$bgPb: 10%; $bgPb: 30%;
$bgPbD: 10%; $bgPbD: 10%;
background-color: darken($bg, $bgPb); background-color: darken($bg, $bgPb);
color: $fg; color: $fg;
@@ -36,6 +36,110 @@
} }
} }
// Status coloring
.ok, .info {
.status-indicator {
color: $colorInfo;
}
}
.alert, .caution, .warning {
.status-indicator, .count {
color: $colorStatusAlert;
}
}
.error, .err {
.status-indicator, .count {
color: $colorStatusError;
}
}
.available {
.status-indicator, .count {
color: $colorStatusAvailable;
}
}
.subdued {
.status-indicator {
color: pullForward($colorStatusBarBg, 40%);
}
}
.status-block-holder {
// Applied to mct-include element
// Contains status.block elements
$transDelay: 1.5s;
$transSpeed: .25s;
display: inline-block;
&.clickable { cursor: pointer; }
&:not(.clickable) { cursor: default; }
&.no-icon .status.block {
.status-indicator {
display: none;
}
}
&.float-right {
float: right;
}
&:not(.no-collapse) .status.block {
.label {
// Max-width silliness is necessary for width transition
@include trans-prop-nice(max-width, $transSpeed, $transDelay);
overflow: hidden;
max-width: 0px;
}
&:hover {
.label {
@include trans-prop-nice(max-width, $transSpeed, 0s);
max-width: 600px;
width: auto;
}
.count {
@include trans-prop-nice(max-width, $transSpeed, 0s);
opacity: 0;
}
}
}
}
.status.block {
$transDelay: 1.5s;
$transSpeed: .25s;
color: $colorStatusDefault;
display: inline-block;
margin-right: $interiorMargin;
.status-indicator,
.label,
.count {
display: inline-block;
vertical-align: top;
}
.status-indicator {
background: none !important;
margin-right: $interiorMarginSm;
&[class*='s-status']:before {
font-size: 1em;
}
}
.count {
@include trans-prop-nice(opacity, $transSpeed, $transDelay);
font-weight: bold;
opacity: 1;
}
.s-button {
background: $colorStatusBtnBg;
padding: 0 $interiorMargin;
height: auto;
line-height: inherit;
}
}
/******************************************************************* MESSAGE BANNERS */ /******************************************************************* MESSAGE BANNERS */
.message { .message {
&.block { &.block {
@@ -185,6 +289,7 @@
> div, > div,
> span { > span {
//@include test(red);
margin-bottom: $interiorMargin; margin-bottom: $interiorMargin;
} }

View File

@@ -11,6 +11,7 @@
} }
min-width: 150px; min-width: 150px;
.l-image-main { .l-image-main {
background-color: $colorPlotBg;
margin-bottom: $interiorMargin; margin-bottom: $interiorMargin;
} }
.l-image-main-controlbar { .l-image-main-controlbar {
@@ -75,7 +76,6 @@
} }
.s-image-main { .s-image-main {
background-color: $colorPlotBg;
border: 1px solid transparent; border: 1px solid transparent;
&.paused { &.paused {
@extend .s-unsynced; @extend .s-unsynced;
@@ -138,51 +138,54 @@
} }
/*************************************** LOCAL CONTROLS */ /*************************************** LOCAL CONTROLS */
.t-imagery { .l-local-controls {
.h-local-controls.h-local-controls-overlay-content { max-width: 200px;
max-width: 200px; min-width: 100px;
min-width: 100px; width: 35%;
width: 35%; input[type="range"] {
align-items: center; display: block;
width: 100%;
&:not(:first-child) {
margin-top: $interiorMarginLg;
}
&:before {
margin-right: $interiorMarginSm;
}
}
.t-reset-btn-holder {
$bc: $scrollbarTrackColorBg;
&:before,
&:after {
border-right: 1px solid $bc;
content:'';
display: block;
width: 5px;
height: 4px;
}
&:before {
border-top: 1px solid $bc;
margin-bottom: 2px;
}
&:after {
border-bottom: 1px solid $bc;
margin-top: 2px;
}
}
&.s-wrapper-transluc {
left: auto;
padding: $interiorMargin $interiorMarginLg; padding: $interiorMargin $interiorMarginLg;
}
input[type="range"] { &.l-flex-row {
display: block; align-items: center;
width: 100%; }
&:not(:first-child) {
margin-top: $interiorMarginLg;
}
&:before {
margin-right: $interiorMarginSm;
}
}
.t-reset-btn-holder {
$bc: $scrollbarTrackColorBg;
&:before,
&:after {
border-right: 1px solid $bc;
content:'';
display: block;
width: 5px;
height: 4px;
}
&:before {
border-top: 1px solid $bc;
margin-bottom: 2px;
}
&:after {
border-bottom: 1px solid $bc;
margin-top: 2px;
}
}
}
} }
/*************************************** WHEN IN FRAME */ /*************************************** WHEN IN FRAME */
.frame .t-imagery { .frame .t-imagery {
.l-image-main-wrapper { .l-image-main-wrapper {

View File

@@ -41,7 +41,6 @@
width: 100%; width: 100%;
.l-form-section { .l-form-section {
margin-bottom: $interiorMarginLg * 2;
position: relative; position: relative;
&.grows { &.grows {
.l-section-body, .l-section-body,
@@ -58,6 +57,7 @@
$m: $interiorMargin; $m: $interiorMargin;
box-sizing: border-box; box-sizing: border-box;
border-top: 1px solid $colorFormLines; border-top: 1px solid $colorFormLines;
margin-bottom: $interiorMarginLg * 2;
padding: $formTBPad 0; padding: $formTBPad 0;
position: relative; position: relative;
@@ -132,7 +132,6 @@
width: auto; width: auto;
order: 2; order: 2;
} }
>.control,
>.controls { >.controls {
flex: 0 0 auto; flex: 0 0 auto;
margin-right: $interiorMargin; margin-right: $interiorMargin;
@@ -259,19 +258,19 @@
} }
} }
} }
}
.form-error { .form-error {
// Block element that visually flags an error and contains a message // Block element that visually flags an error and contains a message
background-color: $colorFormFieldErrorBg; background-color: $colorFormFieldErrorBg;
color: $colorFormFieldErrorFg; color: $colorFormFieldErrorFg;
border-radius: $basicCr; border-radius: $basicCr;
display: block; display: block;
padding: 1px 6px; padding: 1px 6px;
&:before { &:before {
content: $glyph-icon-alert-triangle; content: $glyph-icon-alert-triangle;
display: inline-block; display: inline;
font-family: symbolsfont; font-family: symbolsfont;
margin-right: $interiorMarginSm; margin-right: $interiorMarginSm;
}
} }
} }

View File

@@ -87,6 +87,7 @@
$iconD: $formInputH - ($iconEdgeM * 2); $iconD: $formInputH - ($iconEdgeM * 2);
@extend .icon-magnify; @extend .icon-magnify;
// Adds a magnifying glass before, holds an input and a clear button // Adds a magnifying glass before, holds an input and a clear button
display: inline-block;
position: relative; position: relative;
input[type="search"] { input[type="search"] {
@@ -96,7 +97,6 @@
.menu-icon, .menu-icon,
&:before { &:before {
box-sizing: border-box; box-sizing: border-box;
color: $colorInputIcon;
display: inline-block; display: inline-block;
line-height: inherit; line-height: inherit;
position: absolute; position: absolute;
@@ -107,16 +107,11 @@
&:before { &:before {
// Magnify glass icon // Magnify glass icon
opacity: 0.7;
left: $interiorMargin; left: $interiorMargin;
@include trans-prop-nice(opacity, 250ms); @include trans-prop-nice(color, 250ms);
pointer-events: none; pointer-events: none;
} }
&:hover:before {
opacity: 1;
}
.clear-icon { .clear-icon {
right: $iconEdgeM; right: $iconEdgeM;
// Icon is visible only when there is text input // Icon is visible only when there is text input

View File

@@ -26,20 +26,6 @@
.tabular-holder { .tabular-holder {
@include absPosDefault(); @include absPosDefault();
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
> * {
position: relative;
flex: 0 0 auto;
}
&.l-sticky-headers {
.l-tabular-body {
flex: 1 1 99%;
overflow-x: auto;
}
}
} }
.tabular, .tabular,
@@ -55,20 +41,19 @@ table {
tbody tr, .tbody .tr { tbody tr, .tbody .tr {
width: 100%; width: 100%;
} }
thead, .thead {
border-bottom: 1px solid $colorTabHeaderBorder;
}
thead tr th { &:not(.fixed-header) tr th {
// Add some bg to the headers. Note that this is overwritten below background-color: $colorTabHeaderBg;
// by .mct-table-headers-w when headers are wrapped by that container. }
background-color: $colorTabHeaderBg;
}
tbody, .tbody { tbody, .tbody {
display: table-row-group; display: table-row-group;
tr, .tr {
border-top: 1px solid $colorTabBorder;
}
} }
tr, .tr { tr, .tr {
border-top: 1px solid $colorTabBorder;
display: table-row; display: table-row;
&:first-child .td { &:first-child .td {
border-top: none; border-top: none;
@@ -133,40 +118,41 @@ table {
tbody, .tbody { tbody, .tbody {
top: $tabularHeaderH * 2; top: $tabularHeaderH * 2;
} }
.l-filter { input[type="text"] {
input[type="text"], box-sizing: border-box;
input[type="search"] { width: 100%;
$p: 20px; }
transition: padding 200ms ease-in-out;
box-sizing: border-box;
padding-right: $p; // Fend off from icon
padding-left: $p; // Fend off from icon
width: 100%;
}
&.active {
// When user has typed something, hide the icon and collapse left padding
&:before {
opacity: 0;
}
input[type="text"],
input[type="search"] {
padding-left: $interiorMargin;
}
}
}
} }
&.fixed-header {
height: 100%;
thead, .thead,
tbody tr, .tbody .tr {
display: table;
table-layout: fixed;
}
thead, .thead {
width: calc(100% - 10px);
&:before {
content: "";
display: block;
z-index: 0;
position: absolute;
width: 100%;
height: $tabularHeaderH;
background-color: $colorTabHeaderBg;
}
}
tbody, .tbody {
@include absPosDefault(0);
top: $tabularHeaderH;
display: block;
overflow-y: scroll;
}
}
&.t-event-messages { &.t-event-messages {
td, .td { td, .td {
min-width: 150px; min-width: 150px;
} }
} }
} }
.mct-table-headers-w {
background: $colorTabHeaderBg;
overflow: hidden;
thead tr th {
background: none;
}
}

Some files were not shown because too many files have changed in this diff Show More