mirror of
https://github.com/nasa/openmct.git
synced 2025-01-30 16:13:53 +00:00
Merge remote-tracking branch 'github/master' into open245b
...in preparation to complete merge nasa/openmctweb#257 Conflicts: platform/entanglement/src/actions/CopyAction.js platform/entanglement/src/actions/LinkAction.js platform/entanglement/src/actions/MoveAction.js
This commit is contained in:
commit
7974ffdda2
@ -30,6 +30,7 @@
|
|||||||
"platform/policy",
|
"platform/policy",
|
||||||
"platform/entanglement",
|
"platform/entanglement",
|
||||||
"platform/search",
|
"platform/search",
|
||||||
|
"platform/status",
|
||||||
|
|
||||||
"example/imagery",
|
"example/imagery",
|
||||||
"example/eventGenerator",
|
"example/eventGenerator",
|
||||||
|
@ -1288,6 +1288,22 @@ object, or the current view proxy.
|
|||||||
* `all()`: Get an array of all objects in the selection state. Will include
|
* `all()`: Get an array of all objects in the selection state. Will include
|
||||||
either or both of the view proxy and selected object.
|
either or both of the view proxy and selected object.
|
||||||
|
|
||||||
|
## Workers Category
|
||||||
|
|
||||||
|
The `workers` extension category allows scripts to be run as web workers
|
||||||
|
using the `workerService`.
|
||||||
|
|
||||||
|
An extension of this category has no implementation. The following properties
|
||||||
|
are supported:
|
||||||
|
|
||||||
|
* `key`: A symbolic string used to identify this worker.
|
||||||
|
* `workerUrl`: The path, relative to this bundle's `src` folder, where
|
||||||
|
this worker's source code resides.
|
||||||
|
* `shared`: Optional; a boolean flag which, if true, indicates that this
|
||||||
|
worker should be instantiated as a
|
||||||
|
[`SharedWorker`](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker/SharedWorker).
|
||||||
|
Default value is `false`.
|
||||||
|
|
||||||
# Directives
|
# Directives
|
||||||
|
|
||||||
Open MCT Web defines several Angular directives that are intended for use both
|
Open MCT Web defines several Angular directives that are intended for use both
|
||||||
@ -1883,6 +1899,14 @@ the TelemetrySeries itself, in that order.
|
|||||||
* `getSeries(domainObject)`: Get the latest `TelemetrySeries` (as resulted from
|
* `getSeries(domainObject)`: Get the latest `TelemetrySeries` (as resulted from
|
||||||
a previous `request(...)` call) available for this domain object.
|
a previous `request(...)` call) available for this domain object.
|
||||||
|
|
||||||
|
### Worker Service
|
||||||
|
|
||||||
|
The `workerService` may be used to run web workers defined via the
|
||||||
|
`workers` extension category. It has the following method:
|
||||||
|
|
||||||
|
* `run(key)`: Run the worker identified by the provided `key`. Returns
|
||||||
|
a `Worker` (or `SharedWorker`, if the specified worker is defined
|
||||||
|
as a shared worker); if the `key` is unknown, returns `undefined`.
|
||||||
|
|
||||||
# Models
|
# Models
|
||||||
Domain object models in Open MCT Web are JavaScript objects describing the
|
Domain object models in Open MCT Web are JavaScript objects describing the
|
||||||
@ -2090,6 +2114,31 @@ objects which has a `relationships` property in their model, whose value is an
|
|||||||
object containing key-value pairs, where keys are strings identifying
|
object containing key-value pairs, where keys are strings identifying
|
||||||
relationship types, and values are arrays of domain object identifiers.
|
relationship types, and values are arrays of domain object identifiers.
|
||||||
|
|
||||||
|
## Status Capability
|
||||||
|
|
||||||
|
The `status` capability provides a way to flag domain objects as possessing
|
||||||
|
certain states, represented as simple strings. These states, in turn, are
|
||||||
|
reflected on `mct-representation` elements as classes (prefixed with
|
||||||
|
`s-status-`.) The `status` capability has the following interface:
|
||||||
|
|
||||||
|
* `get()`: Returns an array of all status strings that currently apply
|
||||||
|
to this object.
|
||||||
|
* `set(status, state)`: Adds or removes a status flag to this domain object.
|
||||||
|
The `status` argument is the string to set; `state` is a boolean
|
||||||
|
indicating whether this status should be included (true) or removed (false).
|
||||||
|
* `listen(callback)`: Listen for changes in status. The provided `callback`
|
||||||
|
will be invoked with an array of all current status strings whenever status
|
||||||
|
changes.
|
||||||
|
|
||||||
|
Plug-ins may add and/or recognize arbitrary status flags. Flags defined
|
||||||
|
and/or supported by the platform are:
|
||||||
|
|
||||||
|
Status | CSS Class | Meaning
|
||||||
|
-----------|--------------------|-----------------------------------
|
||||||
|
`editing` | `s-status-editing` | Domain object is being edited.
|
||||||
|
`pending` | `s-status-pending` | Domain object is partially loaded.
|
||||||
|
|
||||||
|
|
||||||
## Telemetry Capability
|
## Telemetry Capability
|
||||||
|
|
||||||
The telemetry capability provides a means for accessing telemetry data
|
The telemetry capability provides a means for accessing telemetry data
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
<li><a href="architecture/">Architecture Overview</a></li>
|
<li><a href="architecture/">Architecture Overview</a></li>
|
||||||
<li><a href="guide/">Developer Guide</a></li>
|
<li><a href="guide/">Developer Guide</a></li>
|
||||||
<li><a href="tutorials/">Tutorials</a></li>
|
<li><a href="tutorials/">Tutorials</a></li>
|
||||||
|
<li><a href="process/">Development Process</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
156
docs/src/process/index.md
Normal file
156
docs/src/process/index.md
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
# Development Cycle
|
||||||
|
|
||||||
|
Development of Open MCT Web occurs on an iterative cycle of
|
||||||
|
sprints and releases.
|
||||||
|
|
||||||
|
* A _sprint_ is three weeks in duration, and represents a
|
||||||
|
set of improvements that can be completed and tested by the
|
||||||
|
development team. Software at the end of the sprint is
|
||||||
|
"semi-stable"; it will have undergone reduced testing and may carry
|
||||||
|
defects or usability issues of lower severity, particularly if
|
||||||
|
there are workarounds.
|
||||||
|
* A _release_ occurs every four sprints. Releases are stable, and
|
||||||
|
will have undergone full acceptance testing to ensure that the
|
||||||
|
software behaves correctly and usably.
|
||||||
|
|
||||||
|
## Roles
|
||||||
|
|
||||||
|
The sprint process assumes the presence of a __project manager.__
|
||||||
|
The project manager is responsible for
|
||||||
|
making tactical decisions about what development work will be
|
||||||
|
performed, and for coordinating with stakeholders to arrive at
|
||||||
|
higher-level strategic decisions about desired functionality
|
||||||
|
and characteristics of the software, major external milestones,
|
||||||
|
and so forth.
|
||||||
|
|
||||||
|
In the absence of a dedicated project manager, this role may be rotated
|
||||||
|
among members of the development team on a per-sprint basis.
|
||||||
|
|
||||||
|
Responsibilities of the project manager including:
|
||||||
|
|
||||||
|
* Maintaining (with agreement of stakeholders) a "road map" of work
|
||||||
|
planned for future releases/sprints; this should be higher-level,
|
||||||
|
usually expressed as "themes",
|
||||||
|
with just enough specificity to gauge feasibility of plans,
|
||||||
|
relate work back to milestones, and identify longer-term
|
||||||
|
dependencies.
|
||||||
|
* Determining (with assistance from the rest of the team) which
|
||||||
|
issues to work on in a given sprint and how they shall be
|
||||||
|
assigned.
|
||||||
|
* Pre-planning subsequent sprints to ensure that all members of the
|
||||||
|
team always have a clear direction.
|
||||||
|
* Scheduling and/or ensuring adherence to
|
||||||
|
[process points](#process-points).
|
||||||
|
* Responding to changes within the sprint (shifting priorities,
|
||||||
|
new issues) and re-allocating work for the sprint as needed.
|
||||||
|
|
||||||
|
## Sprint Calendar
|
||||||
|
|
||||||
|
Certain [process points](#process-points) are regularly scheduled in
|
||||||
|
the sprint cycle.
|
||||||
|
|
||||||
|
### Sprints by Release
|
||||||
|
|
||||||
|
Allocation of work among sprints should be planned relative to release
|
||||||
|
goals and milestones. As a general guideline, higher-risk work (large
|
||||||
|
new features which may carry new defects, major refactoring, design
|
||||||
|
changes with uncertain effects on usability) should be allocated to
|
||||||
|
earlier sprints, allowing for time in later sprints to ensure stability.
|
||||||
|
|
||||||
|
| Sprint | Focus |
|
||||||
|
|:------:|:--------------------------------------------------------|
|
||||||
|
| __1__ | Prototyping, design, experimentation. |
|
||||||
|
| __2__ | New features, refinements, enhancements. |
|
||||||
|
| __3__ | Feature completion, low-risk enhancements, bug fixing. |
|
||||||
|
| __4__ | Stability & quality assurance. |
|
||||||
|
|
||||||
|
### Sprints 1-3
|
||||||
|
|
||||||
|
The first three sprints of a release are primarily centered around
|
||||||
|
development work, with regular acceptance testing in the third
|
||||||
|
week. During this third week, the top priority should be passing
|
||||||
|
acceptance testing (e.g. by resolving any blockers found); any
|
||||||
|
resources not needed for this effort should be used to begin work
|
||||||
|
for the subsequent sprint.
|
||||||
|
|
||||||
|
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||||
|
|:-----:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||||
|
| __1__ | Sprint plan | Tag-up | | | |
|
||||||
|
| __2__ | | Tag-up | | | Code freeze |
|
||||||
|
| __3__ | Sprint acceptance testing | Triage | | _Sprint acceptance testing*_ | Ship |
|
||||||
|
|
||||||
|
* If necessary.
|
||||||
|
|
||||||
|
### Sprint 4
|
||||||
|
|
||||||
|
The software must be stable at the end of the fourth sprint; because of
|
||||||
|
this, the fourth sprint is scheduled differently, with a heightened
|
||||||
|
emphasis on testing.
|
||||||
|
|
||||||
|
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||||
|
|-------:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||||
|
| __1__ | Sprint plan | Tag-up | | | Code freeze |
|
||||||
|
| __2__ | Acceptance testing | Triage | | | |
|
||||||
|
| __3__ | _Acceptance testing*_ | Triage | | _Acceptance testing*_ | Ship |
|
||||||
|
|
||||||
|
* If necessary.
|
||||||
|
|
||||||
|
## Process Points
|
||||||
|
|
||||||
|
* __Sprint plan.__ Project manager allocates issues based on
|
||||||
|
theme(s) for sprint, then reviews with team. Each team member
|
||||||
|
should have roughly two weeks of work allocated (to allow time
|
||||||
|
in the third week for testing of work completed.)
|
||||||
|
* Project manager should also sketch out subsequent sprint so
|
||||||
|
that team may begin work for that sprint during the
|
||||||
|
third week, since testing and blocker resolution is unlikely
|
||||||
|
to require all available resources.
|
||||||
|
* __Tag-up.__ Check in and status update among development team.
|
||||||
|
May amend plan for sprint as-needed.
|
||||||
|
* __Code freeze.__ Any new work from this sprint
|
||||||
|
(features, bug fixes, enhancements) must be integrated by the
|
||||||
|
end of the second week of the sprint. After code freeze
|
||||||
|
(and until the end of the sprint) the only changes that should be
|
||||||
|
merged into the master branch should directly address issues
|
||||||
|
needed to pass acceptance testing.
|
||||||
|
* __Acceptance Testing.__ Structured testing with predefined
|
||||||
|
success criteria. No release should ship without passing
|
||||||
|
acceptance tests. Time is allocated in each sprint for subsequent
|
||||||
|
rounds of acceptance testing if issues are identified during a
|
||||||
|
prior round. Specific details of acceptance testing need to be
|
||||||
|
agreed-upon with relevant stakeholders and delivery recipients,
|
||||||
|
and should be flexible enough to allow changes to plans
|
||||||
|
(e.g. deferring delivery of some feature in order to ensure
|
||||||
|
stability of other features.) Baseline testing includes:
|
||||||
|
* __Testathon.__ Multi-user testing, involving as many users as
|
||||||
|
is feasible, plus development team. Open-ended; should verify
|
||||||
|
completed work from this sprint, test exploratorily for
|
||||||
|
regressions, et cetera.
|
||||||
|
* __24-Hour Test.__ A test to verify that the software remains
|
||||||
|
stable after running for longer durations. May include some
|
||||||
|
combination of automated testing and user verification (e.g.
|
||||||
|
checking to verify that software remains subjectively
|
||||||
|
responsive at conclusion of test.)
|
||||||
|
* __Automated Testing.__ Automated testing integrated into the
|
||||||
|
build. (These tests are verified to pass more often than once
|
||||||
|
per sprint, as they run before any merge to master, but still
|
||||||
|
play an important role in acceptance testing.)
|
||||||
|
* __Sprint Acceptance Testing.__ Subset of Acceptance Testing
|
||||||
|
which should be performed before shipping at the end of any
|
||||||
|
sprint. Time is allocated for a second round of
|
||||||
|
Sprint Acceptance Testing if the first round is not passed.
|
||||||
|
* __Triage.__ Team reviews issues from acceptance testing and uses
|
||||||
|
success criteria to determine whether or not they should block
|
||||||
|
release, then formulates a plan to address these issues before
|
||||||
|
the next round of acceptance testing. Focus here should be on
|
||||||
|
ensuring software passes that testing in order to ship on time;
|
||||||
|
may prefer to disable malfunctioning components and fix them
|
||||||
|
in a subsequent sprint, for example.
|
||||||
|
* __Ship.__ Tag a code snapshot that has passed acceptance
|
||||||
|
testing and deploy that version. (Only true if acceptance
|
||||||
|
testing has passed by this point; if acceptance testing has not
|
||||||
|
been passed, will need to make ad hoc decisions with stakeholders,
|
||||||
|
e.g. "extend the sprint" or "defer shipment until end of next
|
||||||
|
sprint.")
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ define(
|
|||||||
// so it's not checked for here, just formatted for display
|
// so it's not checked for here, just formatted for display
|
||||||
// differently.
|
// differently.
|
||||||
return (i + offset) * 1000 + firstTime * 1000 -
|
return (i + offset) * 1000 + firstTime * 1000 -
|
||||||
(domain === 'yesterday' ? ONE_DAY : 0);
|
(domain === 'yesterday' ? (ONE_DAY * 1000) : 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
generatorData.getRangeValue = function (i, range) {
|
generatorData.getRangeValue = function (i, range) {
|
||||||
|
12
example/mobile/bundle.json
Normal file
12
example/mobile/bundle.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "Mobile",
|
||||||
|
"description": "Allows elements with pertinence to mobile usage and development",
|
||||||
|
"extensions": {
|
||||||
|
"stylesheets": [
|
||||||
|
{
|
||||||
|
"stylesheetUrl": "css/mobile-example.css",
|
||||||
|
"priority": "mandatory"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
26
example/mobile/res/config.rb
Executable file
26
example/mobile/res/config.rb
Executable file
@ -0,0 +1,26 @@
|
|||||||
|
# Require any additional compass plugins here.
|
||||||
|
# require "compass-growl"
|
||||||
|
|
||||||
|
# Set this to the root of your project when deployed:
|
||||||
|
http_path = "/"
|
||||||
|
css_dir = "css"
|
||||||
|
sass_dir = "sass"
|
||||||
|
images_dir = "images"
|
||||||
|
javascripts_dir = "js"
|
||||||
|
|
||||||
|
# You can select your preferred output style here (can be overridden via the command line):
|
||||||
|
# :expanded, :compressed, :nested
|
||||||
|
output_style = :nested
|
||||||
|
|
||||||
|
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||||
|
relative_assets = true
|
||||||
|
|
||||||
|
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||||
|
# line_comments = false
|
||||||
|
|
||||||
|
|
||||||
|
# If you prefer the indented syntax, you might want to regenerate this
|
||||||
|
# project again passing --syntax sass, or you can uncomment this:
|
||||||
|
# preferred_syntax = :sass
|
||||||
|
# and then run:
|
||||||
|
# sass-convert -R --from scss --to sass vfn_platform/static/sass scss && rm -rf sass && mv scss sass
|
103
example/mobile/res/css/mobile-example.css
Normal file
103
example/mobile/res/css/mobile-example.css
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/************************** FEATURES */
|
||||||
|
/************************** VERY INFLUENTIAL GLOBAL DIMENSIONS */
|
||||||
|
/************************** RATIOS */
|
||||||
|
/************************** LAYOUT */
|
||||||
|
/************************** CONTROLS */
|
||||||
|
/************************** PATHS */
|
||||||
|
/************************** TIMINGS */
|
||||||
|
/************************** LIMITS */
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
|
||||||
|
/************************** MOBILE TREE MENU DIMENSIONS */
|
||||||
|
/************************** WINDOW DIMENSIONS FOR RWD */
|
||||||
|
/************************** MEDIA QUERIES: WINDOW CHECKS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
|
/************************** MEDIA QUERIES: WINDOWS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
|
/************************** DEVICE PARAMETERS FOR MENUS/REPRESENTATIONS */
|
||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/* REQUIRES mobile/_constants */
|
||||||
|
@media screen and (orientation: portrait) and (max-width: 514px) and (max-height: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (max-height: 514px) and (max-width: 740px) and (max-device-width: 1024px) and (max-device-height: 799px), screen and (orientation: portrait) and (min-width: 515px) and (max-width: 799px) and (min-height: 741px) and (max-height: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 799px) and (max-device-height: 1024px), screen and (orientation: landscape) and (min-height: 515px) and (max-height: 799px) and (min-width: 741px) and (max-width: 1024px) and (max-device-width: 1024px) and (max-device-height: 799px) {
|
||||||
|
/* line 28, ../sass/mobile-example.scss */
|
||||||
|
.create-btn-holder {
|
||||||
|
display: block !important; } }
|
31
example/mobile/res/sass/mobile-example.scss
Normal file
31
example/mobile/res/sass/mobile-example.scss
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/constants";
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/mobile/constants";
|
||||||
|
@import "../../../../platform/commonUI/general/res/sass/mobile/mixins";
|
||||||
|
|
||||||
|
@include phoneandtablet {
|
||||||
|
// Show the Create button
|
||||||
|
.create-btn-holder {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
}
|
@ -20,15 +20,17 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<span ng-controller="BrowseObjectController">
|
<span ng-controller="BrowseObjectController">
|
||||||
<div class="object-browse-bar bar l-flex">
|
<div class="object-browse-bar l-flex-row">
|
||||||
<div class="items-select left">
|
<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="l-back"></mct-representation>
|
class="flex-elem l-back"></mct-representation>
|
||||||
<mct-representation key="'object-header'" mct-object="domainObject">
|
<mct-representation key="'object-header'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
class="l-flex-row flex-elem grows object-header">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-bar right">
|
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation key="'switcher'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
ng-model="representation">
|
ng-model="representation">
|
||||||
|
@ -28,32 +28,25 @@
|
|||||||
<mct-split-pane class='abs contents'
|
<mct-split-pane class='abs contents'
|
||||||
anchor='left'>
|
anchor='left'>
|
||||||
<div class='split-pane-component treeview pane left'>
|
<div class='split-pane-component treeview pane left'>
|
||||||
<!--<a class="mini-tab-icon anchor-left toggle-pane toggle-search mobile-hide"
|
<div class="abs holder l-flex-col holder-treeview-elements">
|
||||||
title="Enable search"
|
|
||||||
ng-click="modelPaneTree.toggle()"
|
|
||||||
ng-class="{ collapsed : !modelPaneTree.visible() }"
|
|
||||||
ng-style="{ opacity: modelPaneTree.visible()? 0:1 }"></a>-->
|
|
||||||
<div class="holder holder-create-and-search abs l-mobile">
|
|
||||||
<mct-representation key="'create-button'"
|
<mct-representation key="'create-button'"
|
||||||
mct-object="navigatedObject"
|
mct-object="navigatedObject"
|
||||||
mct-device="desktop">
|
class="holder flex-elem create-btn-holder">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
<div class='holder search-holder abs'
|
|
||||||
ng-class="{active: treeModel.search}">
|
|
||||||
<mct-include key="'search'"
|
<mct-include key="'search'"
|
||||||
ng-model="treeModel">
|
ng-model="treeModel"
|
||||||
|
class="holder l-flex-col flex-elem search-holder"
|
||||||
|
ng-class="{ active: treeModel.search, grows: treeModel.search }">
|
||||||
</mct-include>
|
</mct-include>
|
||||||
</div>
|
|
||||||
<div class='tree-holder abs mobile-tree-holder'
|
|
||||||
ng-hide="treeModel.search">
|
|
||||||
<mct-representation key="'tree'"
|
<mct-representation key="'tree'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
parameters="tree"
|
parameters="tree"
|
||||||
ng-model="treeModel">
|
ng-model="treeModel"
|
||||||
|
class="holder flex-elem grows vscroll tree-holder"
|
||||||
|
ng-hide="treeModel.search">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<mct-splitter class="splitter-treeview mobile-hide"></mct-splitter>
|
<mct-splitter class="splitter-treeview mobile-hide"></mct-splitter>
|
||||||
|
|
||||||
@ -63,7 +56,7 @@
|
|||||||
ng-click="modelPaneTree.toggle()"
|
ng-click="modelPaneTree.toggle()"
|
||||||
ng-class="{ collapsed : !modelPaneTree.visible() }"></a>
|
ng-class="{ collapsed : !modelPaneTree.visible() }"></a>
|
||||||
|
|
||||||
<div class='holder holder-object-and-inspector abs l-mobile' id='content-area'
|
<div class='holder holder-object-and-inspector abs' id='content-area'
|
||||||
ng-controller="PaneController as modelPaneInspect"
|
ng-controller="PaneController as modelPaneInspect"
|
||||||
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
|
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
|
||||||
|
|
||||||
|
@ -19,12 +19,12 @@
|
|||||||
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 class='object-header'>
|
<span class='type-icon ui-symbol flex-elem'>{{type.getGlyph()}}</span>
|
||||||
<span class='type-icon ui-symbol'>{{type.getGlyph()}}</span>
|
<span class="l-elem-wrapper l-flex-row flex-elem grows">
|
||||||
<!--span class='type-name mobile-important-hide'>{{type.getName()}}</span-->
|
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
|
||||||
<span class="l-elem-wrapper l-flex">
|
<span class='title-label flex-elem flex-can-shrink'>{{model.name}}</span>
|
||||||
<span ng-if="parameters.mode" class='action'>{{parameters.mode}}</span>
|
<mct-representation
|
||||||
<span class='title-label'>{{model.name}}</span>
|
key="'menu-arrow'"
|
||||||
<mct-representation key="'menu-arrow'" mct-object='domainObject'></mct-representation>
|
mct-object='domainObject'
|
||||||
</span>
|
class="flex-elem"></mct-representation>
|
||||||
</div>
|
</span>
|
@ -22,7 +22,8 @@
|
|||||||
<div class='top-bar edit abs'>
|
<div class='top-bar edit abs'>
|
||||||
<mct-representation key="'object-header'"
|
<mct-representation key="'object-header'"
|
||||||
mct-object="domainObject"
|
mct-object="domainObject"
|
||||||
parameters="{ mode: 'Edit' }">
|
parameters="{ mode: 'Edit' }"
|
||||||
|
class="l-flex-row flex-elem grows object-header">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
<div class='buttons-main btn-bar buttons abs'>
|
<div class='buttons-main btn-bar buttons abs'>
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation key="'switcher'"
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
.col {
|
.col {
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
@include clearfix;
|
@include clearfix;
|
||||||
// background: rgba(#ffcc00, 0.2);
|
|
||||||
float: left;
|
float: left;
|
||||||
margin-left: $ueColMargin;
|
margin-left: $ueColMargin;
|
||||||
padding-left: $interiorMargin;
|
padding-left: $interiorMargin;
|
||||||
@ -98,22 +97,51 @@
|
|||||||
@include display-flex;
|
@include display-flex;
|
||||||
@include flex-wrap(nowrap);
|
@include flex-wrap(nowrap);
|
||||||
.flex-elem {
|
.flex-elem {
|
||||||
|
min-height: 0; // Needed to allow element to shrink within parent
|
||||||
|
position: relative;
|
||||||
&:not(.grows) {
|
&:not(.grows) {
|
||||||
|
@include flex(0 0 auto);
|
||||||
|
&.flex-can-shrink {
|
||||||
@include flex(0 1 auto);
|
@include flex(0 1 auto);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
&.grows {
|
&.grows {
|
||||||
@include flex(1 1 auto);
|
@include flex(1 1 auto);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.flex-container {
|
||||||
|
// Apply to wrapping elements, mct-includes, etc.
|
||||||
.l-flex-row { @include flex-direction(row); }
|
@include display-flex;
|
||||||
.l-flex-col { @include flex-direction(column); }
|
@include flex-wrap(nowrap);
|
||||||
|
@include flex(1 1 auto);
|
||||||
.l-flex {
|
min-height:0;
|
||||||
@extend .l-flex-row;
|
|
||||||
.left {
|
|
||||||
@include flex(1 1 0);
|
|
||||||
padding-right: $interiorMarginLg;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.l-flex-row {
|
||||||
|
@include flex-direction(row);
|
||||||
|
&.flex-elem { @include flex(1 1 auto); }
|
||||||
|
.flex-elem {
|
||||||
|
height: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
.flex-container { @include flex-direction(row); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-flex-col {
|
||||||
|
@include flex-direction(column);
|
||||||
|
.flex-elem {
|
||||||
|
min-height: 0;
|
||||||
|
&.holder:not(:last-child) { margin-bottom: $interiorMarginLg; }
|
||||||
|
}
|
||||||
|
.flex-container { @include flex-direction(column); }
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-fixed {
|
||||||
|
@include flex(0 0 auto);
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-justify-end {
|
||||||
|
@include justify-content(flex-end);
|
||||||
|
}
|
@ -35,15 +35,13 @@ $ltGamma: 20%;
|
|||||||
$btnFontSizeToH: 0.45;
|
$btnFontSizeToH: 0.45;
|
||||||
|
|
||||||
/************************** LAYOUT */
|
/************************** LAYOUT */
|
||||||
$ueTopBarH: 24px; // Change when breadcrumb is enabled
|
$ueTopBarH: 24px;
|
||||||
$ueTopBarEditH: 30px;
|
$ueTopBarEditH: 30px;
|
||||||
$ueTopBarBtnH: 35px;
|
$ueTopBarBtnH: 35px;
|
||||||
$ueFooterH: 25px;
|
$ueFooterH: 25px;
|
||||||
$ueColMargin: 1.5%;
|
$ueColMargin: 1.5%;
|
||||||
$ueAppLogoW: 105px;
|
$ueAppLogoW: 105px;
|
||||||
$ueEditToolBarH: 25px;
|
$ueEditToolBarH: 25px;
|
||||||
$ueBrowseLeftPaneTreeW: 25%;
|
|
||||||
$ueBrowseRightPaneInspectW: 20%;
|
|
||||||
$ueCollapsedPaneEdgeM: 22px;
|
$ueCollapsedPaneEdgeM: 22px;
|
||||||
$uePaneMiniTabH: $ueTopBarH;
|
$uePaneMiniTabH: $ueTopBarH;
|
||||||
$uePaneMiniTabW: 9px;
|
$uePaneMiniTabW: 9px;
|
||||||
@ -51,6 +49,15 @@ $uePaneMiniTabCollapsedW: 11px;
|
|||||||
$ueEditLeftPaneW: 75%;
|
$ueEditLeftPaneW: 75%;
|
||||||
$treeSearchInputBarH: 25px;
|
$treeSearchInputBarH: 25px;
|
||||||
$ueTimeControlH: (33px, 20px, 20px);
|
$ueTimeControlH: (33px, 20px, 20px);
|
||||||
|
// Panes
|
||||||
|
$ueBrowseLeftPaneTreeMinW: 150px;
|
||||||
|
$ueBrowseLeftPaneTreeMaxW: 35%;
|
||||||
|
$ueBrowseLeftPaneTreeW: 25%;
|
||||||
|
$ueBrowseRightPaneInspectMinW: 200px;
|
||||||
|
$ueBrowseRightPaneInspectMaxW: 35%;
|
||||||
|
$ueBrowseRightPaneInspectW: 20%;
|
||||||
|
$ueDesktopMinW: 600px;
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
$ovrTopBarH: 45px;
|
$ovrTopBarH: 45px;
|
||||||
$ovrFooterH: 24px;
|
$ovrFooterH: 24px;
|
||||||
|
@ -142,6 +142,16 @@ mct-container {
|
|||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.off {
|
||||||
|
visibility: hidden;
|
||||||
|
opacity: 0;
|
||||||
|
height: 0;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
margin: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
.sep {
|
.sep {
|
||||||
color: rgba(#fff, 0.2);
|
color: rgba(#fff, 0.2);
|
||||||
}
|
}
|
@ -127,7 +127,6 @@ label.checkbox.custom {
|
|||||||
&:before {
|
&:before {
|
||||||
@include border-radius($basicCr * .75);
|
@include border-radius($basicCr * .75);
|
||||||
background: $bg;
|
background: $bg;
|
||||||
//border-bottom: 1px solid lighten($bg, 10%);
|
|
||||||
@include box-shadow(inset rgba(black, 0.4) 0 1px 2px);
|
@include box-shadow(inset rgba(black, 0.4) 0 1px 2px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
content: " ";
|
content: " ";
|
||||||
@ -202,7 +201,6 @@ label.checkbox.custom {
|
|||||||
|
|
||||||
/******************************************************** OBJECT-HEADER */
|
/******************************************************** OBJECT-HEADER */
|
||||||
.object-header {
|
.object-header {
|
||||||
//@include test();
|
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
|
||||||
> .type-icon {
|
> .type-icon {
|
||||||
@ -213,8 +211,6 @@ label.checkbox.custom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.l-elem-wrapper {
|
.l-elem-wrapper {
|
||||||
//@include test(#66f, 0.2);
|
|
||||||
@include justify-content(flex-start);
|
|
||||||
mct-representation {
|
mct-representation {
|
||||||
// Holds the context-available item
|
// Holds the context-available item
|
||||||
// Must have min-width to make flex work properly
|
// Must have min-width to make flex work properly
|
||||||
@ -228,19 +224,15 @@ label.checkbox.custom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.title-label {
|
.title-label {
|
||||||
//@include test(green, 0.9);
|
|
||||||
color: $colorObjHdrTxt;
|
color: $colorObjHdrTxt;
|
||||||
@include ellipsize();
|
@include ellipsize();
|
||||||
//color: pushBack($colorBodyFg, 40%);
|
|
||||||
@include webkitProp(flex, '0 1 auto');
|
@include webkitProp(flex, '0 1 auto');
|
||||||
padding-right: 0.35em; // For context arrow. Done with em's so pad is relative to the scale of the text.
|
padding-right: 0.35em; // For context arrow. Done with em's so pad is relative to the scale of the text.
|
||||||
//position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.context-available {
|
.context-available {
|
||||||
font-size: 0.7em;
|
font-size: 0.7em;
|
||||||
@include webkitProp(flex, '0 0 1');
|
@include webkitProp(flex, '0 0 1');
|
||||||
//margin-right: $interiorMargin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@include desktop {
|
@include desktop {
|
||||||
@ -303,7 +295,6 @@ label.checkbox.custom {
|
|||||||
@include border-radius($basicCr);
|
@include border-radius($basicCr);
|
||||||
@include boxIncised(0.3, 4px);
|
@include boxIncised(0.3, 4px);
|
||||||
background: $colorProgressBarOuter;
|
background: $colorProgressBarOuter;
|
||||||
//border:1px solid $colorProgressBarOuter;
|
|
||||||
.progress-amt {
|
.progress-amt {
|
||||||
@include border-radius($basicCr);
|
@include border-radius($basicCr);
|
||||||
@include boxShdw();
|
@include boxShdw();
|
||||||
@ -343,8 +334,6 @@ label.checkbox.custom {
|
|||||||
.slider {
|
.slider {
|
||||||
$knobH: 100%; //14px;
|
$knobH: 100%; //14px;
|
||||||
.slot {
|
.slot {
|
||||||
// @include border-radius($basicCr * .75);
|
|
||||||
//@include sliderTrack();
|
|
||||||
width: auto;
|
width: auto;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -400,14 +389,11 @@ label.checkbox.custom {
|
|||||||
width: 230px;
|
width: 230px;
|
||||||
.l-month-year-pager {
|
.l-month-year-pager {
|
||||||
$pagerW: 20px;
|
$pagerW: 20px;
|
||||||
//@include test();
|
|
||||||
//font-size: 0.8rem;
|
|
||||||
height: $r1H;
|
height: $r1H;
|
||||||
margin-bottom: $interiorMargin;
|
margin-bottom: $interiorMargin;
|
||||||
position: relative;
|
position: relative;
|
||||||
.pager,
|
.pager,
|
||||||
.val {
|
.val {
|
||||||
//@include test(red);
|
|
||||||
@extend .abs;
|
@extend .abs;
|
||||||
}
|
}
|
||||||
.pager {
|
.pager {
|
||||||
@ -454,7 +440,6 @@ label.checkbox.custom {
|
|||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
@include flex(1 0);
|
@include flex(1 0);
|
||||||
//@include test();
|
|
||||||
margin-left: 1px;
|
margin-left: 1px;
|
||||||
padding: $interiorMargin;
|
padding: $interiorMargin;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@ -512,8 +497,6 @@ label.checkbox.custom {
|
|||||||
@include background-image(linear-gradient(lighten($bg, $gr), $bg 20px));
|
@include background-image(linear-gradient(lighten($bg, $gr), $bg 20px));
|
||||||
@include border-radius(2px);
|
@include border-radius(2px);
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
//@include boxShdwSubtle();
|
|
||||||
//border-top: 1px solid lighten($bg, 20%);
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@include background-image(linear-gradient(lighten($hc, $gr), $hc 20px));
|
@include background-image(linear-gradient(lighten($hc, $gr), $hc 20px));
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
margin: 0 0 2px 0; // Needed to avoid dropshadow from being clipped by parent containers
|
margin: 0 0 2px 0; // Needed to avoid dropshadow from being clipped by parent containers
|
||||||
}
|
}
|
||||||
padding: 0 $interiorMargin;
|
padding: 0 $interiorMargin;
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
line-height: $formInputH;
|
line-height: $formInputH;
|
||||||
select {
|
select {
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
//@include test(red);
|
//@include test(red);
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: 1;
|
z-index: 3;
|
||||||
&:after {
|
&:after {
|
||||||
// The handle
|
// The handle
|
||||||
content:"";
|
content:"";
|
||||||
@ -43,7 +43,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
&:active {
|
&:active {
|
||||||
//@include test();
|
|
||||||
&:after {
|
&:after {
|
||||||
background-color: $colorSplitterActive !important;
|
background-color: $colorSplitterActive !important;
|
||||||
}
|
}
|
||||||
@ -122,11 +121,3 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.browse-area .splitter {
|
|
||||||
top: 0; //$ueTopBarH + $interiorMarginLg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-area .splitter {
|
|
||||||
top: 0;
|
|
||||||
}*/
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* REQUIRES /platform/commonUI/general/res/sass/_constants.scss */
|
||||||
|
|
||||||
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
|
/************************** MOBILE REPRESENTATION ITEMS DIMENSIONS */
|
||||||
$mobileListIconSize: 30px;
|
$mobileListIconSize: 30px;
|
||||||
$mobileTitleDescH: 35px;
|
$mobileTitleDescH: 35px;
|
||||||
@ -32,51 +34,31 @@ $mobileTreeItemH: 35px;
|
|||||||
$mobileTreeItemIndent: 20px;
|
$mobileTreeItemIndent: 20px;
|
||||||
$mobileTreeRightArrowW: 30px;
|
$mobileTreeRightArrowW: 30px;
|
||||||
|
|
||||||
/************************** WINDOW DIMENSIONS FOR RWD */
|
/************************** DEVICE WIDTHS */
|
||||||
|
// IMPORTANT! Usage assumes that ranges are mutually exclusive and have no gaps
|
||||||
$phoMaxW: 514px;
|
$phoMaxW: 514px;
|
||||||
$phoMaxH: 740px;
|
|
||||||
|
|
||||||
$tabMinW: 515px;
|
$tabMinW: 515px;
|
||||||
$tabMaxW: 799px;
|
$tabMaxW: 1280px;
|
||||||
|
$desktopMinW: 1281px;
|
||||||
$tabMinH: 741px;
|
|
||||||
$tabMaxH: 1024px;
|
|
||||||
|
|
||||||
$compMinW: 800px;
|
|
||||||
$compMinH: 1025px;
|
|
||||||
|
|
||||||
/************************** MEDIA QUERIES: WINDOW CHECKS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
/************************** MEDIA QUERIES: WINDOW CHECKS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
$screenPortrait: "screen and (orientation: portrait)";
|
$screenPortrait: "screen and (orientation: portrait)";
|
||||||
$screenLandscape: "screen and (orientation: landscape)";
|
$screenLandscape: "screen and (orientation: landscape)";
|
||||||
|
|
||||||
$mobileDevice: "(max-device-width: #{$tabMaxW}) and (max-device-height: #{$tabMaxH})";
|
$mobileDevice: "(max-device-width: #{$tabMaxW})";
|
||||||
$mobileDeviceEmu: "(max-device-width: #{$tabMaxH}) and (max-device-height: #{$tabMaxW})";
|
|
||||||
|
|
||||||
$phonePortraitCheck: "(max-width: #{$phoMaxW}) and (max-height: #{$phoMaxH})";
|
$phoneCheck: "(max-device-width: #{$phoMaxW})";
|
||||||
$phoneLandscapeCheck: "(max-height: #{$phoMaxW}) and (max-width: #{$phoMaxH})";
|
$tabletCheck: $mobileDevice;
|
||||||
|
$desktopCheck: "(min-device-width: #{$desktopMinW})";
|
||||||
$tabWidPorCheck: "(min-width: #{$tabMinW}) and (max-width: #{$tabMaxW})";
|
|
||||||
$tabHeiPorCheck: "(min-height: #{$tabMinH}) and (max-height: #{$tabMaxH})";
|
|
||||||
$tabletPortraitCheck: "#{$tabWidPorCheck} and #{$tabHeiPorCheck}";
|
|
||||||
|
|
||||||
$tabWidLanCheck: "(min-height: #{$tabMinW}) and (max-height: #{$tabMaxW})";
|
|
||||||
$tabHeiLanCheck: "(min-width: #{$tabMinH}) and (max-width: #{$tabMaxH})";
|
|
||||||
$tabletLandscapeCheck: "#{$tabWidLanCheck} and #{$tabHeiLanCheck}";
|
|
||||||
|
|
||||||
$desktopPortraitCheck: "(min-device-width: #{$compMinW}) and (min-device-height: #{$compMinH})";
|
|
||||||
$desktopLandscapeCheck: "(min-device-width: #{$compMinH}) and (min-device-height: #{$compMinW})";
|
|
||||||
|
|
||||||
/************************** MEDIA QUERIES: WINDOWS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
/************************** MEDIA QUERIES: WINDOWS FOR SPECIFIC ORIENTATIONS FOR EACH DEVICE */
|
||||||
$phonePortrait: "#{$screenPortrait} and #{$phonePortraitCheck} and #{$mobileDevice}";
|
$phonePortrait: "#{$screenPortrait} and #{$phoneCheck} and #{$mobileDevice}";
|
||||||
$phoneLandscape: "#{$screenLandscape} and #{$phoneLandscapeCheck} and #{$mobileDevice}";
|
$phoneLandscape: "#{$screenLandscape} and #{$phoneCheck} and #{$mobileDevice}";
|
||||||
$phoneLandscapeEmu: "#{$screenLandscape} and #{$phoneLandscapeCheck} and #{$mobileDeviceEmu}";
|
|
||||||
|
|
||||||
$tabletPortrait: "#{$screenPortrait} and #{$tabletPortraitCheck} and #{$mobileDevice}";
|
$tabletPortrait: "#{$screenPortrait} and #{$tabletCheck} and #{$mobileDevice}";
|
||||||
$tabletLandscape: "#{$screenLandscape} and #{$tabletLandscapeCheck} and #{$mobileDevice}";
|
$tabletLandscape: "#{$screenLandscape} and #{$tabletCheck} and #{$mobileDevice}";
|
||||||
$tabletLandscapeEmu: "#{$screenLandscape} and #{$tabletLandscapeCheck} and #{$mobileDeviceEmu}";
|
|
||||||
|
|
||||||
$desktopPortrait: "screen and #{$desktopPortraitCheck}";
|
$desktop: "screen and #{$desktopCheck}";
|
||||||
$desktopLandscape: "screen and #{$desktopLandscapeCheck}";
|
|
||||||
|
|
||||||
/************************** DEVICE PARAMETERS FOR MENUS/REPRESENTATIONS */
|
/************************** DEVICE PARAMETERS FOR MENUS/REPRESENTATIONS */
|
||||||
$proporMenuOnly: 90%;
|
$proporMenuOnly: 90%;
|
||||||
|
@ -36,16 +36,23 @@
|
|||||||
//@include test();
|
//@include test();
|
||||||
@include slMenuTransitions;
|
@include slMenuTransitions;
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
#content-area {
|
.holder-object-and-inspector {
|
||||||
@include slMenuTransitions;
|
@include slMenuTransitions;
|
||||||
|
left: $bodyMargin;
|
||||||
|
right: $bodyMargin;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.holder.holder-create-and-search {
|
.create-btn-holder {
|
||||||
right: $bodyMargin !important;
|
// Hide the create button by default in mobile;
|
||||||
|
// This can be overridden by the examples/mobile bundle
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.holder.holder-treeview-elements {
|
||||||
|
right: $bodyMargin !important;
|
||||||
|
}
|
||||||
|
|
||||||
// When the tree is hidden, these are the
|
// When the tree is hidden, these are the
|
||||||
// classes used for the left menu and the
|
// classes used for the left menu and the
|
||||||
@ -55,10 +62,6 @@
|
|||||||
// is hidden.
|
// is hidden.
|
||||||
.pane.left.treeview {
|
.pane.left.treeview {
|
||||||
@include trans-prop-nice(opacity, 150ms);
|
@include trans-prop-nice(opacity, 150ms);
|
||||||
//right: 100% !important;
|
|
||||||
//width: auto !important;
|
|
||||||
//overflow-y: hidden;
|
|
||||||
//overflow-x: hidden;
|
|
||||||
opacity: 0 !important;
|
opacity: 0 !important;
|
||||||
}
|
}
|
||||||
.pane.right.items {
|
.pane.right.items {
|
||||||
@ -72,7 +75,6 @@
|
|||||||
// causing cut/copy/paste menu to
|
// causing cut/copy/paste menu to
|
||||||
// not appear. Should me moved in
|
// not appear. Should me moved in
|
||||||
// future to properly work
|
// future to properly work
|
||||||
//@include user-select(none);
|
|
||||||
|
|
||||||
// Sets the left tree menu when the tree is shown.
|
// Sets the left tree menu when the tree is shown.
|
||||||
.pane.left.treeview {
|
.pane.left.treeview {
|
||||||
@ -100,7 +102,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.object-browse-bar {
|
.object-browse-bar {
|
||||||
//@include test();
|
|
||||||
left: 45px !important;
|
left: 45px !important;
|
||||||
.context-available {
|
.context-available {
|
||||||
opacity: 1 !important;
|
opacity: 1 !important;
|
||||||
@ -148,7 +149,7 @@
|
|||||||
.pane.right.items {
|
.pane.right.items {
|
||||||
left: 0 !important;
|
left: 0 !important;
|
||||||
@include transform(translateX($proporMenuOnly));
|
@include transform(translateX($proporMenuOnly));
|
||||||
#content-area {
|
.holder-object-and-inspector {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,12 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
/* REQUIRES /platform/commonUI/general/res/sass/mobile/_constants.scss */
|
||||||
|
|
||||||
// Phones in any orientation
|
// Phones in any orientation
|
||||||
@mixin phone {
|
@mixin phone {
|
||||||
@media #{$phonePortrait},
|
@media #{$phonePortrait},
|
||||||
#{$phoneLandscape},
|
#{$phoneLandscape} {
|
||||||
#{$phoneLandscapeEmu} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,8 +39,7 @@
|
|||||||
|
|
||||||
// Phones in landscape orientation
|
// Phones in landscape orientation
|
||||||
@mixin phoneLandscape {
|
@mixin phoneLandscape {
|
||||||
@media #{$phoneLandscape},
|
@media #{$phoneLandscape} {
|
||||||
#{$phoneLandscapeEmu} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,8 +47,7 @@
|
|||||||
// Tablets in any orientation
|
// Tablets in any orientation
|
||||||
@mixin tablet {
|
@mixin tablet {
|
||||||
@media #{$tabletPortrait},
|
@media #{$tabletPortrait},
|
||||||
#{$tabletLandscape},
|
#{$tabletLandscape} {
|
||||||
#{$tabletLandscapeEmu} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,8 +61,7 @@
|
|||||||
|
|
||||||
// Tablets in landscape orientation
|
// Tablets in landscape orientation
|
||||||
@mixin tabletLandscape {
|
@mixin tabletLandscape {
|
||||||
@media #{$tabletLandscape},
|
@media #{$tabletLandscape} {
|
||||||
#{$tabletLandscapeEmu} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,10 +70,8 @@
|
|||||||
@mixin phoneandtablet {
|
@mixin phoneandtablet {
|
||||||
@media #{$phonePortrait},
|
@media #{$phonePortrait},
|
||||||
#{$phoneLandscape},
|
#{$phoneLandscape},
|
||||||
#{$phoneLandscapeEmu},
|
|
||||||
#{$tabletPortrait},
|
#{$tabletPortrait},
|
||||||
#{$tabletLandscape},
|
#{$tabletLandscape} {
|
||||||
#{$tabletLandscapeEmu} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -84,17 +80,14 @@
|
|||||||
@mixin desktopandtablet {
|
@mixin desktopandtablet {
|
||||||
@media #{$tabletPortrait},
|
@media #{$tabletPortrait},
|
||||||
#{$tabletLandscape},
|
#{$tabletLandscape},
|
||||||
#{$tabletLandscapeEmu},
|
#{$desktop} {
|
||||||
#{$desktopPortrait},
|
|
||||||
#{$desktopLandscape} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Desktop monitors in any orientation
|
// Desktop monitors in any orientation
|
||||||
@mixin desktop {
|
@mixin desktop {
|
||||||
@media #{$desktopPortrait},
|
@media #{$desktop} {
|
||||||
#{$desktopLandscape} {
|
|
||||||
@content
|
@content
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
// Override the Create menu for mobile
|
// Override the Create menu for mobile
|
||||||
@include phoneandtablet {
|
@include phoneandtablet {
|
||||||
.menu-element {
|
|
||||||
.super-menu {
|
.super-menu {
|
||||||
$d: 250px;
|
$d: 250px;
|
||||||
width: $d;
|
width: $d;
|
||||||
@ -39,5 +38,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -20,11 +20,9 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
$yBarW: 60px;
|
$yBarW: 60px;
|
||||||
$yLabelW: auto;
|
$yLabelW: 10px;
|
||||||
$xBarH: 32px;
|
$xBarH: 32px;
|
||||||
$legendH: 20px;
|
$legendH: 20px;
|
||||||
//$colorHash: rgba(white, 0.3); // MOVED INTO CONSTANTS
|
|
||||||
//$styleHash: dashed; // MOVED INTO CONSTANTS
|
|
||||||
$swatchD: 8px;
|
$swatchD: 8px;
|
||||||
$plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBarW); // Top, right, bottom, left
|
$plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBarW); // Top, right, bottom, left
|
||||||
|
|
||||||
@ -36,7 +34,6 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
||||||
.gl-plot-axis-area {
|
.gl-plot-axis-area {
|
||||||
// @include test(green);
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
&.gl-plot-x {
|
&.gl-plot-x {
|
||||||
top: auto;
|
top: auto;
|
||||||
@ -59,7 +56,7 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
.gl-plot-coords {
|
.gl-plot-coords {
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
@include border-radius($controlCr);
|
@include border-radius($controlCr);
|
||||||
background: black; //rgba($colorKey, 0.5);
|
background: black;
|
||||||
color: lighten($colorBodyFg, 30%);
|
color: lighten($colorBodyFg, 30%);
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -88,11 +85,9 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
|
|
||||||
.gl-plot-label,
|
.gl-plot-label,
|
||||||
.l-plot-label {
|
.l-plot-label {
|
||||||
// @include test(yellow);
|
|
||||||
color: $colorPlotLabelFg;
|
color: $colorPlotLabelFg;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
// text-transform: uppercase;
|
|
||||||
|
|
||||||
&.gl-plot-x-label,
|
&.gl-plot-x-label,
|
||||||
&.l-plot-x-label {
|
&.l-plot-x-label {
|
||||||
@ -117,18 +112,24 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gl-plot-x-options,
|
||||||
.gl-plot-y-options {
|
.gl-plot-y-options {
|
||||||
$h: 32px;
|
$h: 32px;
|
||||||
// @include test();
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
|
||||||
right: auto;
|
|
||||||
bottom: auto;
|
|
||||||
left: $yLabelW + $interiorMargin;
|
|
||||||
margin-top: $h / -2;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
min-height: $h;
|
min-height: $h;
|
||||||
width: $h;
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gl-plot-x-options {
|
||||||
|
top: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gl-plot-y-options {
|
||||||
|
@include transform(translateY(-50%));
|
||||||
|
min-width: 150px; // Need this due to enclosure of .select
|
||||||
|
top: 50%;
|
||||||
|
left: $yLabelW + $interiorMargin * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gl-plot-hash {
|
.gl-plot-hash {
|
||||||
@ -214,21 +215,13 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: $swatchD;
|
height: $swatchD;
|
||||||
width: $swatchD;
|
width: $swatchD;
|
||||||
//margin-right: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
&[class*='s-limit'] {
|
|
||||||
.title-label {
|
|
||||||
//color: #fff;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.gl-plot-legend {
|
.gl-plot-legend {
|
||||||
.plot-legend-item {
|
.plot-legend-item {
|
||||||
//@include test();
|
|
||||||
@include border-radius($smallCr);
|
@include border-radius($smallCr);
|
||||||
//color: #fff;
|
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
padding: 0px $itemPadLR;
|
padding: 0px $itemPadLR;
|
||||||
.plot-color-swatch {
|
.plot-color-swatch {
|
||||||
@ -250,7 +243,6 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
|
|
||||||
.gl-plot-tick,
|
.gl-plot-tick,
|
||||||
.tick-label {
|
.tick-label {
|
||||||
// @include test(red);
|
|
||||||
font-size: 0.7rem;
|
font-size: 0.7rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -277,7 +269,6 @@ $plotDisplayArea: ($legendH + $interiorMargin, 0, $xBarH + $interiorMargin, $yBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
.gl-plot-tick {
|
.gl-plot-tick {
|
||||||
// @include test(red);
|
|
||||||
&.gl-plot-x-tick-label {
|
&.gl-plot-x-tick-label {
|
||||||
top: $interiorMargin;
|
top: $interiorMargin;
|
||||||
}
|
}
|
||||||
|
@ -20,30 +20,22 @@
|
|||||||
* at runtime from the About dialog for additional information.
|
* at runtime from the About dialog for additional information.
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
.abs.search-holder {
|
.clear-icon,
|
||||||
//@include test(#990000);
|
.menu-icon {
|
||||||
height: $treeSearchInputBarH;
|
cursor: pointer;
|
||||||
bottom: 0;
|
font-family: symbolsfont;
|
||||||
&.active {
|
@include trans-prop-nice((opacity, color), 150ms);
|
||||||
height: auto;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
top: 23px;
|
|
||||||
|
|
||||||
// Align with the top of the divider bar, below create button
|
|
||||||
//margin-top: 10px; // CH comment out
|
|
||||||
z-index:5;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search {
|
.clear-icon {
|
||||||
|
// 'x' in circle icon
|
||||||
|
&:before {
|
||||||
|
content: '\e607';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.holder-search {
|
||||||
$iconWidth: 20px;
|
$iconWidth: 20px;
|
||||||
$leftMargin: 6px;
|
|
||||||
$rightPadding: 5px;
|
|
||||||
@include webkitVal(display, flex);
|
|
||||||
//display: flex;
|
|
||||||
@include webkitProp(flex-direction, column);
|
|
||||||
//flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.search-bar {
|
.search-bar {
|
||||||
$textInputHeight: 19px; // This is equal to the default value, 19px
|
$textInputHeight: 19px; // This is equal to the default value, 19px
|
||||||
@ -52,38 +44,25 @@
|
|||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
max-width: 250px;
|
max-width: 250px;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
|
||||||
.search-input,
|
|
||||||
.search-icon {
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
height: $treeSearchInputBarH;
|
height: $treeSearchInputBarH;
|
||||||
line-height: $treeSearchInputBarH;
|
line-height: $treeSearchInputBarH;
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-icon,
|
&:before,
|
||||||
.clear-icon,
|
.clear-icon,
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
//@include test(#008800);
|
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
color: $colorInputIcon;
|
color: $colorInputIcon;
|
||||||
height: $iconD; width: $iconD;
|
height: $iconD;
|
||||||
|
width: $iconD;
|
||||||
line-height: $iconD;
|
line-height: $iconD;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
top: $iconEdgeM;
|
top: $iconEdgeM;
|
||||||
}
|
}
|
||||||
|
|
||||||
.clear-icon,
|
|
||||||
.menu-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
@include transition(color, .25s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -92,31 +71,21 @@
|
|||||||
|
|
||||||
// Make work for mct-control textfield
|
// Make work for mct-control textfield
|
||||||
input {
|
input {
|
||||||
width: 100%;
|
width: inherit; // was 100%
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-icon {
|
&:before {
|
||||||
//color: $colorItemFg;
|
// Magnify glass icon
|
||||||
|
content:'\4d';
|
||||||
|
font-family: symbolsfont;
|
||||||
left: $interiorMarginSm;
|
left: $interiorMarginSm;
|
||||||
transition: visibility .15s, opacity .15s, color .2s;
|
@include trans-prop-nice(color, 250ms);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
&.content {
|
|
||||||
// Make icon invisible whenever there is text input
|
|
||||||
//visibility: hidden;
|
|
||||||
//opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make icon invisible when the text input is focused
|
|
||||||
.search-input:focus + div.search-icon {
|
|
||||||
//visibility: hidden;
|
|
||||||
//opacity: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make icon lighten when hovering over search bar
|
// Make icon lighten when hovering over search bar
|
||||||
.search-input:hover + div.search-icon {
|
&:hover:before {
|
||||||
color: pullForward($colorInputIcon, 10%);
|
color: pullForward($colorInputIcon, 10%);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,10 +95,7 @@
|
|||||||
// Icon is visible only when there is text input
|
// Icon is visible only when there is text input
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
&.show {
|
||||||
transition: visibility .15s, opacity .15s, color .2s;
|
|
||||||
|
|
||||||
&.content {
|
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
@ -140,6 +106,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-icon {
|
.menu-icon {
|
||||||
|
// 'v' invoke menu icon
|
||||||
|
&:before { content: '\76'; }
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
padding-right: $iconEdgeM;
|
padding-right: $iconEdgeM;
|
||||||
right: $iconEdgeM;
|
right: $iconEdgeM;
|
||||||
@ -152,43 +120,19 @@
|
|||||||
|
|
||||||
.search-menu-holder {
|
.search-menu-holder {
|
||||||
float: right;
|
float: right;
|
||||||
//margin-top: $textInputHeight - 2px;
|
|
||||||
//left: -50px;
|
|
||||||
left: -20px;
|
left: -20px;
|
||||||
|
z-index: 70;
|
||||||
z-index: 1;
|
|
||||||
|
|
||||||
transition: visibility .05s, opacity .05s;
|
transition: visibility .05s, opacity .05s;
|
||||||
|
|
||||||
&.off {
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hovering reveals menu
|
|
||||||
.menu-icon:hover + div.search-menu-holder {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
div.search-menu-holder:hover {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-filter-display {
|
.active-filter-display {
|
||||||
//order: 2;
|
|
||||||
$s: 0.65em;
|
$s: 0.65em;
|
||||||
$p: $interiorMargin;
|
$p: $interiorMargin;
|
||||||
@include border-radius($basicCr);
|
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
line-height: 130%;
|
line-height: 130%;
|
||||||
padding: $p 0;
|
|
||||||
padding-left: $s * 2.25;
|
padding-left: $s * 2.25;
|
||||||
font-size: $s;
|
font-size: $s;
|
||||||
//background-color: rgba(#000, 0.3);
|
|
||||||
//border-radius: $basicCr;
|
|
||||||
margin-top: $interiorMarginSm;
|
|
||||||
|
|
||||||
|
|
||||||
.clear-filters-icon {
|
.clear-filters-icon {
|
||||||
color: $colorInputIcon;
|
color: $colorInputIcon;
|
||||||
@ -198,43 +142,28 @@
|
|||||||
left: 1px;
|
left: 1px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition looks weird when the results list has none
|
|
||||||
//transition: visibility .2s, opacity .2s;
|
|
||||||
|
|
||||||
&.off {
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
height: 0;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-scroll {
|
.search-results {
|
||||||
order: 3;
|
@include trans-prop-nice((opacity, visibility), 250ms);
|
||||||
margin-top: 4px;
|
margin-top: $interiorMarginLg; // Always include margin here to fend off the search input
|
||||||
|
padding-right: $interiorMargin;
|
||||||
// Adjustable scrolling size
|
.hint {
|
||||||
overflow-y: auto;
|
margin-bottom: $interiorMarginLg;
|
||||||
top: auto;
|
font-size: 0.65em;
|
||||||
height: auto;
|
opacity: 0.6;
|
||||||
max-height: 100%;
|
}
|
||||||
position: relative;
|
&.active {
|
||||||
|
visibility: visible;
|
||||||
.load-icon {
|
opacity: 1;
|
||||||
position: relative;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.load-more-button {
|
.load-more-button {
|
||||||
margin-top: $interiorMargin 0;
|
@include transform(translateX(-50%));
|
||||||
font-size: 0.8em;
|
display: inline-block;
|
||||||
position: relative;
|
margin-top: $interiorMargin;
|
||||||
left: 50%;
|
padding: 0 $interiorMarginLg;
|
||||||
margin-left: -45px;
|
font-size: 0.75em;
|
||||||
text-align: center;
|
margin-left: 50%;
|
||||||
width: 90px;
|
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,13 @@
|
|||||||
border-color: lighten($bc, 10%);
|
border-color: lighten($bc, 10%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
>.object-header.abs {
|
.object-top-bar {
|
||||||
//@include test(red);
|
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
height: $ohH;
|
height: $ohH;
|
||||||
line-height: $ohH;
|
line-height: $ohH;
|
||||||
|
.left {
|
||||||
|
padding-right: $interiorMarginLg;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
>.object-holder.abs {
|
>.object-holder.abs {
|
||||||
top: $ohH + $interiorMargin;
|
top: $ohH + $interiorMargin;
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contents {
|
.contents {
|
||||||
$myM: 0; //$interiorMargin;
|
$myM: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: $myM;
|
top: $myM;
|
||||||
@ -46,37 +46,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.bar {
|
|
||||||
.icon.major {
|
|
||||||
margin-right: $interiorMargin;
|
|
||||||
}
|
|
||||||
&.abs {
|
|
||||||
text-wrap: none;
|
|
||||||
white-space: nowrap;
|
|
||||||
&.left,
|
|
||||||
.left {
|
|
||||||
width: 45%;
|
|
||||||
right: auto;
|
|
||||||
}
|
|
||||||
&.right,
|
|
||||||
.right {
|
|
||||||
width: 45%;
|
|
||||||
left: auto;
|
|
||||||
text-align: right;
|
|
||||||
.icon.major {
|
|
||||||
margin-left: $interiorMargin * 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.l-flex,
|
|
||||||
&.l-flex {
|
|
||||||
.left,
|
|
||||||
.right {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.user-environ {
|
.user-environ {
|
||||||
.browse-area,
|
.browse-area,
|
||||||
.editor {
|
.editor {
|
||||||
@ -117,12 +86,10 @@
|
|||||||
background: $colorFooterBg;
|
background: $colorFooterBg;
|
||||||
color: lighten($colorBodyBg, 30%);
|
color: lighten($colorBodyBg, 30%);
|
||||||
font-size: .7rem;
|
font-size: .7rem;
|
||||||
|
|
||||||
.status-holder {
|
.status-holder {
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
@include absPosDefault($interiorMargin);
|
@include absPosDefault($interiorMargin);
|
||||||
@include ellipsize();
|
@include ellipsize();
|
||||||
//line-height: $ueFooterH - ($interiorMargin * 2);
|
|
||||||
right: 120px;
|
right: 120px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
@ -141,25 +108,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.browse-mode {
|
|
||||||
.split-layout {
|
|
||||||
.split-pane-component.pane {
|
|
||||||
//@include test(green);
|
|
||||||
&.treeview.left {
|
|
||||||
min-width: 150px;
|
|
||||||
max-width: 800px;
|
|
||||||
width: $ueBrowseLeftPaneTreeW;
|
|
||||||
}
|
|
||||||
&.t-inspect.right {
|
|
||||||
min-width: 200px;
|
|
||||||
max-width: 600px;
|
|
||||||
//padding-left: $ueCollapsedPaneEdgeM; // Allow room for mini-tab element
|
|
||||||
width: $ueBrowseRightPaneInspectW;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.edit-mode {
|
.edit-mode {
|
||||||
.split-layout {
|
.split-layout {
|
||||||
.split-pane-component.pane.right {
|
.split-pane-component.pane.right {
|
||||||
@ -180,7 +128,6 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
height: $ueTopBarH;
|
height: $ueTopBarH;
|
||||||
line-height: $ueTopBarH;
|
line-height: $ueTopBarH;
|
||||||
margin-bottom: $interiorMargin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.primary-pane {
|
.primary-pane {
|
||||||
@ -188,30 +135,7 @@
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.treeview.left {
|
|
||||||
//.create-btn-holder {
|
|
||||||
// //bottom: auto;
|
|
||||||
// //top: 0;
|
|
||||||
// height: $ueTopBarH;
|
|
||||||
// .wrapper.menu-element {
|
|
||||||
// position: absolute;
|
|
||||||
// bottom: $interiorMargin;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
.holder-create-and-search{
|
|
||||||
|
|
||||||
}
|
|
||||||
.search-holder {
|
|
||||||
top: $ueTopBarH + $interiorMarginLg;
|
|
||||||
}
|
|
||||||
.tree-holder {
|
|
||||||
overflow: auto;
|
|
||||||
top: $ueTopBarH + $interiorMarginLg + $treeSearchInputBarH + $interiorMargin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mini-tab-icon.toggle-pane {
|
.mini-tab-icon.toggle-pane {
|
||||||
//@include test(blue, 0.3);
|
|
||||||
z-index: 5;
|
z-index: 5;
|
||||||
@include desktop {
|
@include desktop {
|
||||||
$d: $uePaneMiniTabH;
|
$d: $uePaneMiniTabH;
|
||||||
@ -256,7 +180,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.items {
|
&.items {
|
||||||
.object-browse-bar {
|
.object-browse-bar {
|
||||||
.left.abs,
|
.left.abs,
|
||||||
@ -268,32 +191,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.split-layout {
|
.split-layout {
|
||||||
&.horizontal {
|
|
||||||
// Slides up and down
|
|
||||||
> .pane {
|
|
||||||
// @include test();
|
|
||||||
margin-top: $interiorMargin;
|
|
||||||
&:first-child {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* &.vertical {
|
|
||||||
// Slides left and right
|
|
||||||
> .pane.left {
|
|
||||||
> .holder {
|
|
||||||
left: $bodyMargin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
> .pane.right {
|
|
||||||
> .holder {
|
|
||||||
right: $bodyMargin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// Specific elements margins
|
// Specific elements margins
|
||||||
.holder.holder-create-and-search {
|
.holder.holder-treeview-elements {
|
||||||
top: $bodyMargin;
|
top: $bodyMargin;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: $bodyMargin;
|
bottom: $bodyMargin;
|
||||||
@ -314,7 +213,6 @@
|
|||||||
bottom: $bodyMargin;
|
bottom: $bodyMargin;
|
||||||
left: $bodyMargin;
|
left: $bodyMargin;
|
||||||
right: $bodyMargin;
|
right: $bodyMargin;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -347,19 +245,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************** OBJECT BROWSE BAR */
|
||||||
.object-browse-bar {
|
.object-browse-bar {
|
||||||
//@include test(blue);
|
@include absPosDefault(0, visible); // Must use visible to avoid hiding view switcher menu
|
||||||
@include absPosDefault(0, hidden);
|
|
||||||
@include box-sizing(border-box);
|
@include box-sizing(border-box);
|
||||||
height: $ueTopBarH;
|
height: $ueTopBarH;
|
||||||
line-height: $ueTopBarH;
|
line-height: $ueTopBarH;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
padding-right: $interiorMarginLg * 2;
|
padding-right: $interiorMarginLg;
|
||||||
.l-back {
|
.l-back {
|
||||||
display: inline-block;
|
|
||||||
float: left;
|
|
||||||
margin-right: $interiorMarginLg;
|
margin-right: $interiorMarginLg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -370,24 +266,22 @@
|
|||||||
// right representation.
|
// right representation.
|
||||||
.pane-tree-hidden {
|
.pane-tree-hidden {
|
||||||
// Sets the left tree menu when the tree is hidden.
|
// Sets the left tree menu when the tree is hidden.
|
||||||
//.pane.left.treeview,
|
|
||||||
.tree-holder,
|
.tree-holder,
|
||||||
.splitter-treeview,
|
.splitter-treeview,
|
||||||
.holder-create-and-search {
|
.holder-treeview-elements {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pane-tree-showing {
|
.pane-tree-showing {
|
||||||
// Sets the left tree menu when the tree is shown.
|
// Sets the left tree menu when the tree is shown.
|
||||||
//.pane.left.treeview,
|
|
||||||
.tree-holder,
|
.tree-holder,
|
||||||
.splitter-treeview {
|
.splitter-treeview {
|
||||||
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 250ms);
|
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 250ms);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.holder-create-and-search {
|
.holder-treeview-elements {
|
||||||
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 200ms);
|
@include trans-prop-nice(opacity, $dur: 250ms, $delay: 200ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -401,8 +295,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.pane-inspect-hidden {
|
.pane-inspect-hidden {
|
||||||
.l-object-and-inspector {
|
.l-object-and-inspector {
|
||||||
|
.t-inspect {
|
||||||
|
z-index: 1 !important; // Move down so that primary pane elements are clickable
|
||||||
|
}
|
||||||
.l-inspect,
|
.l-inspect,
|
||||||
.splitter-inspect {
|
.splitter-inspect {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
@ -411,6 +309,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@include desktop {
|
@include desktop {
|
||||||
|
.holder-all {
|
||||||
|
min-width: $ueDesktopMinW;
|
||||||
|
}
|
||||||
|
.split-layout {
|
||||||
|
.split-pane-component.pane {
|
||||||
|
&.treeview.left {
|
||||||
|
min-width: $ueBrowseLeftPaneTreeMinW;
|
||||||
|
max-width: $ueBrowseLeftPaneTreeMaxW;
|
||||||
|
width: $ueBrowseLeftPaneTreeW;
|
||||||
|
}
|
||||||
|
&.t-inspect.right {
|
||||||
|
min-width: $ueBrowseRightPaneInspectMinW;
|
||||||
|
max-width: $ueBrowseRightPaneInspectMaxW;
|
||||||
|
width: $ueBrowseRightPaneInspectW;
|
||||||
|
z-index: 3; // Must lift up beyond primary pane to allow overflow to go underneath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.pane.treeview.left .tree-holder {
|
.pane.treeview.left .tree-holder {
|
||||||
padding-right: $interiorMargin;
|
padding-right: $interiorMargin;
|
||||||
}
|
}
|
||||||
@ -420,8 +336,10 @@
|
|||||||
.pane-inspect-hidden .l-object-and-inspector {
|
.pane-inspect-hidden .l-object-and-inspector {
|
||||||
.pane.left { right: $ueCollapsedPaneEdgeM !important; }
|
.pane.left { right: $ueCollapsedPaneEdgeM !important; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.pane:not(.resizing) {
|
.pane:not(.resizing) {
|
||||||
@include trans-prop-nice-resize-w(250ms);
|
@include trans-prop-nice-resize-w(250ms);
|
||||||
}
|
}
|
||||||
|
.pane.primary-pane .object-browse-bar {
|
||||||
|
min-width: 200px; // Needed for nice display when primary pane is constrained severely via splitters
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@
|
|||||||
</input>
|
</input>
|
||||||
<a class="ui-symbol icon icon-calendar"
|
<a class="ui-symbol icon icon-calendar"
|
||||||
ng-if="structure.format === 'utc' || !structure.format"
|
ng-if="structure.format === 'utc' || !structure.format"
|
||||||
ng-click="pickerActive = !pickerActive">
|
ng-click="picker.active = !picker.active">
|
||||||
</a>
|
</a>
|
||||||
<mct-popup ng-if="pickerActive">
|
<mct-popup ng-if="picker.active">
|
||||||
<div mct-click-elsewhere="pickerActive = false">
|
<div mct-click-elsewhere="picker.active = false">
|
||||||
<mct-control key="'datetime-picker'"
|
<mct-control key="'datetime-picker'"
|
||||||
ng-model="ngModel"
|
ng-model="ngModel"
|
||||||
field="field"
|
field="field"
|
||||||
|
@ -69,9 +69,12 @@ define(
|
|||||||
updateFromModel($scope.ngModel[$scope.field]);
|
updateFromModel($scope.ngModel[$scope.field]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$scope.picker = { active: false };
|
||||||
|
|
||||||
$scope.$watch('structure.format', setFormat);
|
$scope.$watch('structure.format', setFormat);
|
||||||
$scope.$watch('ngModel[field]', updateFromModel);
|
$scope.$watch('ngModel[field]', updateFromModel);
|
||||||
$scope.$watch('textValue', updateFromView);
|
$scope.$watch('textValue', updateFromView);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DateTimeFieldController;
|
return DateTimeFieldController;
|
||||||
|
@ -51,6 +51,10 @@ define(
|
|||||||
position = [ rect.left, rect.top ],
|
position = [ rect.left, rect.top ],
|
||||||
popup = popupService.display(div, position);
|
popup = popupService.display(div, position);
|
||||||
|
|
||||||
|
// TODO: Handle in CSS;
|
||||||
|
// https://github.com/nasa/openmctweb/issues/298
|
||||||
|
div.css('z-index', 75);
|
||||||
|
|
||||||
transclude(function (clone) {
|
transclude(function (clone) {
|
||||||
div.append(clone);
|
div.append(clone);
|
||||||
});
|
});
|
||||||
|
@ -91,6 +91,10 @@ define(
|
|||||||
expect(mockScope.textValue).toEqual("1977-05-25 17:30:00");
|
expect(mockScope.textValue).toEqual("1977-05-25 17:30:00");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("exposes toggle state for date-time picker", function () {
|
||||||
|
expect(mockScope.picker.active).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
describe("when user input is invalid", function () {
|
describe("when user input is invalid", function () {
|
||||||
var newText, oldValue;
|
var newText, oldValue;
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -72,8 +72,6 @@ $colorInputBg: $colorGenBg;
|
|||||||
$colorInputFg: $colorBodyFg;
|
$colorInputFg: $colorBodyFg;
|
||||||
$colorFormText: pushBack($colorBodyFg, 10%);
|
$colorFormText: pushBack($colorBodyFg, 10%);
|
||||||
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
||||||
$colorSelectBg: #ddd;
|
|
||||||
$colorSelectFg: $colorBodyFg;
|
|
||||||
|
|
||||||
// Inspector
|
// Inspector
|
||||||
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||||
@ -83,6 +81,22 @@ $colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
|
|||||||
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
|
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
|
||||||
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||||
|
|
||||||
|
// Status colors, mainly used for messaging and item ancillary symbols
|
||||||
|
$colorStatusFg: #fff;
|
||||||
|
$colorStatusDefault: #ccc;
|
||||||
|
$colorStatusInfo: #60ba7b;
|
||||||
|
$colorStatusAlert: #ffb66c;
|
||||||
|
$colorStatusError: #c96b68;
|
||||||
|
$colorProgressBarOuter: rgba(#000, 0.1);
|
||||||
|
$colorProgressBarAmt: #0a0;
|
||||||
|
$progressBarHOverlay: 15px;
|
||||||
|
$progressBarStripeW: 20px;
|
||||||
|
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
|
||||||
|
|
||||||
|
// Selects
|
||||||
|
$colorSelectBg: #ddd;
|
||||||
|
$colorSelectFg: $colorBodyFg;
|
||||||
|
|
||||||
// Limits and staleness colors//
|
// Limits and staleness colors//
|
||||||
$colorTelemFresh: pullForward($colorBodyFg, 20%);
|
$colorTelemFresh: pullForward($colorBodyFg, 20%);
|
||||||
$colorTelemStale: pushBack($colorBodyFg, 20%);
|
$colorTelemStale: pushBack($colorBodyFg, 20%);
|
||||||
|
@ -96,7 +96,7 @@
|
|||||||
"provides": "actionService",
|
"provides": "actionService",
|
||||||
"type": "provider",
|
"type": "provider",
|
||||||
"implementation": "actions/ActionProvider.js",
|
"implementation": "actions/ActionProvider.js",
|
||||||
"depends": [ "actions[]" ]
|
"depends": [ "actions[]", "$log" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"provides": "actionService",
|
"provides": "actionService",
|
||||||
@ -222,7 +222,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "topic",
|
"key": "topic",
|
||||||
"implementation": "services/Topic.js"
|
"implementation": "services/Topic.js",
|
||||||
|
"depends": [ "$log" ]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"key": "contextualize",
|
"key": "contextualize",
|
||||||
|
@ -39,9 +39,11 @@ define(
|
|||||||
* @imeplements {ActionService}
|
* @imeplements {ActionService}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function ActionProvider(actions) {
|
function ActionProvider(actions, $log) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
this.$log = $log;
|
||||||
|
|
||||||
// Build up look-up tables
|
// Build up look-up tables
|
||||||
this.actions = actions;
|
this.actions = actions;
|
||||||
this.actionsByKey = {};
|
this.actionsByKey = {};
|
||||||
@ -74,6 +76,7 @@ define(
|
|||||||
var context = (actionContext || {}),
|
var context = (actionContext || {}),
|
||||||
category = context.category,
|
category = context.category,
|
||||||
key = context.key,
|
key = context.key,
|
||||||
|
$log = this.$log,
|
||||||
candidates;
|
candidates;
|
||||||
|
|
||||||
// Instantiate an action; invokes the constructor and
|
// Instantiate an action; invokes the constructor and
|
||||||
@ -103,12 +106,31 @@ define(
|
|||||||
// appliesTo method of given actions (if defined), and
|
// appliesTo method of given actions (if defined), and
|
||||||
// instantiate those applicable actions.
|
// instantiate those applicable actions.
|
||||||
function createIfApplicable(actions, context) {
|
function createIfApplicable(actions, context) {
|
||||||
return (actions || []).filter(function (Action) {
|
function isApplicable(Action) {
|
||||||
return Action.appliesTo ?
|
return Action.appliesTo ? Action.appliesTo(context) : true;
|
||||||
Action.appliesTo(context) : true;
|
}
|
||||||
}).map(function (Action) {
|
|
||||||
|
function instantiate(Action) {
|
||||||
|
try {
|
||||||
return instantiateAction(Action, context);
|
return instantiateAction(Action, context);
|
||||||
});
|
} catch (e) {
|
||||||
|
$log.error([
|
||||||
|
"Could not instantiate action",
|
||||||
|
Action.key,
|
||||||
|
"due to:",
|
||||||
|
e.message
|
||||||
|
].join(" "));
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDefined(action) {
|
||||||
|
return action !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (actions || []).filter(isApplicable)
|
||||||
|
.map(instantiate)
|
||||||
|
.filter(isDefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Match actions to the provided context by comparing "key"
|
// Match actions to the provided context by comparing "key"
|
||||||
|
@ -26,6 +26,8 @@ define(
|
|||||||
function () {
|
function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
var ERROR_PREFIX = "Error when notifying listener: ";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The `topic` service provides a way to create both named,
|
* The `topic` service provides a way to create both named,
|
||||||
* shared listeners and anonymous, private listeners.
|
* shared listeners and anonymous, private listeners.
|
||||||
@ -46,7 +48,7 @@ define(
|
|||||||
* @returns {Function}
|
* @returns {Function}
|
||||||
* @memberof platform/core
|
* @memberof platform/core
|
||||||
*/
|
*/
|
||||||
function Topic() {
|
function Topic($log) {
|
||||||
var topics = {};
|
var topics = {};
|
||||||
|
|
||||||
function createTopic() {
|
function createTopic() {
|
||||||
@ -63,7 +65,11 @@ define(
|
|||||||
},
|
},
|
||||||
notify: function (message) {
|
notify: function (message) {
|
||||||
listeners.forEach(function (listener) {
|
listeners.forEach(function (listener) {
|
||||||
|
try {
|
||||||
listener(message);
|
listener(message);
|
||||||
|
} catch (e) {
|
||||||
|
$log.error(ERROR_PREFIX + e.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -156,8 +156,15 @@ define(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the default model for an object of this type. Note that
|
||||||
|
* this method returns a clone of the original model, so if using this
|
||||||
|
* method heavily, consider caching the result to optimize performance.
|
||||||
|
*
|
||||||
|
* @return {object} The default model for an object of this type.
|
||||||
|
*/
|
||||||
TypeImpl.prototype.getInitialModel = function () {
|
TypeImpl.prototype.getInitialModel = function () {
|
||||||
return this.typeDef.model || {};
|
return JSON.parse(JSON.stringify(this.typeDef.model || {}));
|
||||||
};
|
};
|
||||||
|
|
||||||
TypeImpl.prototype.getDefinition = function () {
|
TypeImpl.prototype.getDefinition = function () {
|
||||||
|
@ -30,7 +30,8 @@ define(
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
describe("The action provider", function () {
|
describe("The action provider", function () {
|
||||||
var actions,
|
var mockLog,
|
||||||
|
actions,
|
||||||
actionProvider;
|
actionProvider;
|
||||||
|
|
||||||
function SimpleAction() {
|
function SimpleAction() {
|
||||||
@ -62,6 +63,10 @@ define(
|
|||||||
MetadataAction.key = "metadata";
|
MetadataAction.key = "metadata";
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
mockLog = jasmine.createSpyObj(
|
||||||
|
'$log',
|
||||||
|
['error', 'warn', 'info', 'debug']
|
||||||
|
);
|
||||||
actions = [
|
actions = [
|
||||||
SimpleAction,
|
SimpleAction,
|
||||||
CategorizedAction,
|
CategorizedAction,
|
||||||
@ -137,6 +142,42 @@ define(
|
|||||||
expect(provided[0].getMetadata()).toEqual("custom metadata");
|
expect(provided[0].getMetadata()).toEqual("custom metadata");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("when actions throw errors during instantiation", function () {
|
||||||
|
var errorText,
|
||||||
|
provided;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
errorText = "some error text";
|
||||||
|
|
||||||
|
function BadAction() {
|
||||||
|
throw new Error(errorText);
|
||||||
|
}
|
||||||
|
|
||||||
|
provided = new ActionProvider(
|
||||||
|
[ SimpleAction, BadAction ],
|
||||||
|
mockLog
|
||||||
|
).getActions();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("logs an error", function () {
|
||||||
|
expect(mockLog.error)
|
||||||
|
.toHaveBeenCalledWith(jasmine.any(String));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("reports the error's message", function () {
|
||||||
|
expect(
|
||||||
|
mockLog.error.mostRecentCall.args[0].indexOf(errorText)
|
||||||
|
).not.toEqual(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("still provides valid actions", function () {
|
||||||
|
expect(provided.length).toEqual(1);
|
||||||
|
expect(provided[0].perform()).toEqual("simple");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
@ -28,13 +28,18 @@ define(
|
|||||||
|
|
||||||
describe("The 'topic' service", function () {
|
describe("The 'topic' service", function () {
|
||||||
var topic,
|
var topic,
|
||||||
|
mockLog,
|
||||||
testMessage,
|
testMessage,
|
||||||
mockCallback;
|
mockCallback;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
testMessage = { someKey: "some value"};
|
testMessage = { someKey: "some value"};
|
||||||
|
mockLog = jasmine.createSpyObj(
|
||||||
|
'$log',
|
||||||
|
[ 'error', 'warn', 'info', 'debug' ]
|
||||||
|
);
|
||||||
mockCallback = jasmine.createSpy('callback');
|
mockCallback = jasmine.createSpy('callback');
|
||||||
topic = new Topic();
|
topic = new Topic(mockLog);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("notifies listeners on a topic", function () {
|
it("notifies listeners on a topic", function () {
|
||||||
@ -65,6 +70,21 @@ define(
|
|||||||
expect(mockCallback).toHaveBeenCalledWith(testMessage);
|
expect(mockCallback).toHaveBeenCalledWith(testMessage);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("is robust against errors thrown by listeners", function () {
|
||||||
|
var mockBadCallback = jasmine.createSpy("bad-callback"),
|
||||||
|
t = topic();
|
||||||
|
|
||||||
|
mockBadCallback.andCallFake(function () {
|
||||||
|
throw new Error("I'm afraid I can't do that.");
|
||||||
|
});
|
||||||
|
|
||||||
|
t.listen(mockBadCallback);
|
||||||
|
t.listen(mockCallback);
|
||||||
|
|
||||||
|
t.notify(testMessage);
|
||||||
|
expect(mockCallback).toHaveBeenCalledWith(testMessage);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -101,6 +101,12 @@ define(
|
|||||||
expect(type.getInitialModel().someKey).toEqual("some value");
|
expect(type.getInitialModel().someKey).toEqual("some value");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("provides a fresh initial model each time", function () {
|
||||||
|
var model = type.getInitialModel();
|
||||||
|
model.someKey = "some other value";
|
||||||
|
expect(type.getInitialModel().someKey).toEqual("some value");
|
||||||
|
});
|
||||||
|
|
||||||
it("provides type properties", function () {
|
it("provides type properties", function () {
|
||||||
expect(type.getProperties().length).toEqual(1);
|
expect(type.getProperties().length).toEqual(1);
|
||||||
});
|
});
|
||||||
|
@ -146,6 +146,14 @@ define(
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AbstractComposeAction.appliesTo = function (context) {
|
||||||
|
var applicableObject =
|
||||||
|
context.selectedObject || context.domainObject;
|
||||||
|
|
||||||
|
return !!(applicableObject &&
|
||||||
|
applicableObject.hasCapability('context'));
|
||||||
|
};
|
||||||
|
|
||||||
return AbstractComposeAction;
|
return AbstractComposeAction;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -60,6 +60,8 @@ define(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CopyAction.prototype = Object.create(AbstractComposeAction.prototype);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates user about progress of copy. Should not be invoked by
|
* Updates user about progress of copy. Should not be invoked by
|
||||||
* client code under any circumstances.
|
* client code under any circumstances.
|
||||||
@ -145,6 +147,9 @@ define(
|
|||||||
return AbstractComposeAction.prototype.perform.call(this)
|
return AbstractComposeAction.prototype.perform.call(this)
|
||||||
.then(success, error, notification);
|
.then(success, error, notification);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CopyAction.appliesTo = AbstractComposeAction.appliesTo;
|
||||||
|
|
||||||
return CopyAction;
|
return CopyAction;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -35,15 +35,15 @@ define(
|
|||||||
* @memberof platform/entanglement
|
* @memberof platform/entanglement
|
||||||
*/
|
*/
|
||||||
function LinkAction(policyService, locationService, linkService, context) {
|
function LinkAction(policyService, locationService, linkService, context) {
|
||||||
return new AbstractComposeAction(
|
AbstractComposeAction.apply(
|
||||||
policyService,
|
this,
|
||||||
locationService,
|
[policyService, locationService, linkService, context, "Link"]
|
||||||
linkService,
|
|
||||||
context,
|
|
||||||
"Link"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LinkAction.prototype = Object.create(AbstractComposeAction.prototype);
|
||||||
|
LinkAction.appliesTo = AbstractComposeAction.appliesTo;
|
||||||
|
|
||||||
return LinkAction;
|
return LinkAction;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -35,15 +35,15 @@ define(
|
|||||||
* @memberof platform/entanglement
|
* @memberof platform/entanglement
|
||||||
*/
|
*/
|
||||||
function MoveAction(policyService, locationService, moveService, context) {
|
function MoveAction(policyService, locationService, moveService, context) {
|
||||||
return new AbstractComposeAction(
|
AbstractComposeAction.apply(
|
||||||
policyService,
|
this,
|
||||||
locationService,
|
[policyService, locationService, moveService, context, "Move"]
|
||||||
moveService,
|
|
||||||
context,
|
|
||||||
"Move"
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MoveAction.prototype = Object.create(AbstractComposeAction.prototype);
|
||||||
|
MoveAction.appliesTo = AbstractComposeAction.appliesTo;
|
||||||
|
|
||||||
return MoveAction;
|
return MoveAction;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -102,6 +102,28 @@ define(
|
|||||||
composeService = new MockCopyService();
|
composeService = new MockCopyService();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("are only applicable to domain objects with a context", function () {
|
||||||
|
var noContextObject = domainObjectFactory({
|
||||||
|
name: 'selectedObject',
|
||||||
|
model: { name: 'selectedObject' },
|
||||||
|
capabilities: {}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(AbstractComposeAction.appliesTo({
|
||||||
|
selectedObject: selectedObject
|
||||||
|
})).toBe(true);
|
||||||
|
expect(AbstractComposeAction.appliesTo({
|
||||||
|
domainObject: selectedObject
|
||||||
|
})).toBe(true);
|
||||||
|
|
||||||
|
expect(AbstractComposeAction.appliesTo({
|
||||||
|
selectedObject: noContextObject
|
||||||
|
})).toBe(false);
|
||||||
|
expect(AbstractComposeAction.appliesTo({
|
||||||
|
domainObject: noContextObject
|
||||||
|
})).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
describe("with context from context-action", function () {
|
describe("with context from context-action", function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
|
@ -38,7 +38,8 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function WorkerService($window, workers) {
|
function WorkerService($window, workers) {
|
||||||
var workerUrls = {};
|
var workerUrls = {},
|
||||||
|
sharedWorkers = {};
|
||||||
|
|
||||||
function addWorker(worker) {
|
function addWorker(worker) {
|
||||||
var key = worker.key;
|
var key = worker.key;
|
||||||
@ -48,12 +49,15 @@ define(
|
|||||||
worker.bundle.sources,
|
worker.bundle.sources,
|
||||||
worker.scriptUrl
|
worker.scriptUrl
|
||||||
].join("/");
|
].join("/");
|
||||||
|
sharedWorkers[key] = worker.shared;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(workers || []).forEach(addWorker);
|
(workers || []).forEach(addWorker);
|
||||||
this.workerUrls = workerUrls;
|
this.workerUrls = workerUrls;
|
||||||
|
this.sharedWorkers = sharedWorkers;
|
||||||
this.Worker = $window.Worker;
|
this.Worker = $window.Worker;
|
||||||
|
this.SharedWorker = $window.SharedWorker;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,12 +65,17 @@ define(
|
|||||||
* that has been registered under the `workers` category
|
* that has been registered under the `workers` category
|
||||||
* of extension.
|
* of extension.
|
||||||
*
|
*
|
||||||
|
* This will return either a Worker or a SharedWorker,
|
||||||
|
* depending on whether a `shared` flag has been specified
|
||||||
|
* on the the extension definition for the referenced worker.
|
||||||
|
*
|
||||||
* @param {string} key symbolic identifier for the worker
|
* @param {string} key symbolic identifier for the worker
|
||||||
* @returns {Worker} the running Worker
|
* @returns {Worker | SharedWorker} the running Worker
|
||||||
*/
|
*/
|
||||||
WorkerService.prototype.run = function (key) {
|
WorkerService.prototype.run = function (key) {
|
||||||
var scriptUrl = this.workerUrls[key],
|
var scriptUrl = this.workerUrls[key],
|
||||||
Worker = this.Worker;
|
Worker = this.sharedWorkers[key] ?
|
||||||
|
this.SharedWorker : this.Worker;
|
||||||
return scriptUrl && Worker && new Worker(scriptUrl);
|
return scriptUrl && Worker && new Worker(scriptUrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,10 +30,14 @@ define(
|
|||||||
var mockWindow,
|
var mockWindow,
|
||||||
testWorkers,
|
testWorkers,
|
||||||
mockWorker,
|
mockWorker,
|
||||||
|
mockSharedWorker,
|
||||||
service;
|
service;
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockWindow = jasmine.createSpyObj('$window', ['Worker']);
|
mockWindow = jasmine.createSpyObj(
|
||||||
|
'$window',
|
||||||
|
['Worker', 'SharedWorker']
|
||||||
|
);
|
||||||
testWorkers = [
|
testWorkers = [
|
||||||
{
|
{
|
||||||
key: 'abc',
|
key: 'abc',
|
||||||
@ -49,11 +53,19 @@ define(
|
|||||||
key: 'xyz',
|
key: 'xyz',
|
||||||
scriptUrl: 'bad.js',
|
scriptUrl: 'bad.js',
|
||||||
bundle: { path: 'bad', sources: 'bad' }
|
bundle: { path: 'bad', sources: 'bad' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'a-shared-worker',
|
||||||
|
shared: true,
|
||||||
|
scriptUrl: 'c.js',
|
||||||
|
bundle: { path: 'a', sources: 'b' }
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
mockWorker = {};
|
mockWorker = {};
|
||||||
|
mockSharedWorker = {};
|
||||||
|
|
||||||
mockWindow.Worker.andReturn(mockWorker);
|
mockWindow.Worker.andReturn(mockWorker);
|
||||||
|
mockWindow.SharedWorker.andReturn(mockSharedWorker);
|
||||||
|
|
||||||
service = new WorkerService(mockWindow, testWorkers);
|
service = new WorkerService(mockWindow, testWorkers);
|
||||||
});
|
});
|
||||||
@ -68,6 +80,12 @@ define(
|
|||||||
expect(mockWindow.Worker).toHaveBeenCalledWith('x/y/z.js');
|
expect(mockWindow.Worker).toHaveBeenCalledWith('x/y/z.js');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("allows workers to be shared", function () {
|
||||||
|
expect(service.run('a-shared-worker')).toBe(mockSharedWorker);
|
||||||
|
expect(mockWindow.SharedWorker)
|
||||||
|
.toHaveBeenCalledWith('a/b/c.js');
|
||||||
|
});
|
||||||
|
|
||||||
it("returns undefined for unknown workers", function () {
|
it("returns undefined for unknown workers", function () {
|
||||||
expect(service.run('def')).toBeUndefined();
|
expect(service.run('def')).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
<div class="t-imagery" ng-controller="ImageryController as imagery">
|
<div class="t-imagery" ng-controller="ImageryController as imagery">
|
||||||
<!-- Main image -->
|
|
||||||
<div
|
<div
|
||||||
class="l-image-main-wrapper"
|
class="l-image-main-wrapper"
|
||||||
ng-mouseenter="showLocalControls = true;"
|
ng-mouseenter="showLocalControls = true;"
|
||||||
@ -33,8 +32,8 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="l-image-main-controlbar l-flex bar">
|
<div class="l-image-main-controlbar l-flex-row">
|
||||||
<div class="left">
|
<div class="left flex-elem grows">
|
||||||
<a
|
<a
|
||||||
class="s-btn show-thumbs sm hidden"
|
class="s-btn show-thumbs sm hidden"
|
||||||
ng-click="showThumbsBubble = (showThumbsBubble)? false:true"
|
ng-click="showThumbsBubble = (showThumbsBubble)? false:true"
|
||||||
@ -43,7 +42,7 @@
|
|||||||
<span class="l-time">{{imagery.getTime()}}</span>
|
<span class="l-time">{{imagery.getTime()}}</span>
|
||||||
<span class="l-date">{{imagery.getDate()}}</span>
|
<span class="l-date">{{imagery.getDate()}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right flex-elem">
|
||||||
<a
|
<a
|
||||||
class="s-btn pause-play"
|
class="s-btn pause-play"
|
||||||
ng-click="imagery.paused(!imagery.paused())"
|
ng-click="imagery.paused(!imagery.paused())"
|
||||||
|
@ -20,12 +20,15 @@
|
|||||||
at runtime from the About dialog for additional information.
|
at runtime from the About dialog for additional information.
|
||||||
-->
|
-->
|
||||||
<div class="frame frame-template abs">
|
<div class="frame frame-template abs">
|
||||||
<div class="bar abs l-flex object-header object-top-bar">
|
<div class="abs object-top-bar l-flex-row">
|
||||||
<div class="left">
|
<div class="left flex-elem l-flex-row grows">
|
||||||
<mct-representation key="'object-header'" mct-object="domainObject">
|
<mct-representation
|
||||||
|
key="'object-header'"
|
||||||
|
mct-object="domainObject"
|
||||||
|
class="l-flex-row flex-elem object-header grows">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
</div>
|
||||||
<div class="btn-bar right">
|
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed">
|
||||||
<mct-representation key="'switcher'"
|
<mct-representation key="'switcher'"
|
||||||
ng-model="representation"
|
ng-model="representation"
|
||||||
mct-object="domainObject">
|
mct-object="domainObject">
|
||||||
|
@ -113,7 +113,7 @@ define(
|
|||||||
Math.floor(position.x / self.gridSize[0]),
|
Math.floor(position.x / self.gridSize[0]),
|
||||||
Math.floor(position.y / self.gridSize[1])
|
Math.floor(position.y / self.gridSize[1])
|
||||||
],
|
],
|
||||||
dimensions: DEFAULT_DIMENSIONS
|
dimensions: self.defaultDimensions()
|
||||||
};
|
};
|
||||||
// Mark change as persistable
|
// Mark change as persistable
|
||||||
if ($scope.commit) {
|
if ($scope.commit) {
|
||||||
|
@ -192,6 +192,29 @@ define(
|
|||||||
expect(parseInt(styleB.width, 10)).toBeGreaterThan(63);
|
expect(parseInt(styleB.width, 10)).toBeGreaterThan(63);
|
||||||
expect(parseInt(styleB.width, 10)).toBeGreaterThan(31);
|
expect(parseInt(styleB.width, 10)).toBeGreaterThan(31);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("ensures a minimum frame size on drop", function () {
|
||||||
|
var style;
|
||||||
|
|
||||||
|
// Start with a very small frame size
|
||||||
|
testModel.layoutGrid = [ 1, 1 ];
|
||||||
|
mockScope.$watch.calls[0].args[1](testModel.layoutGrid);
|
||||||
|
|
||||||
|
// Notify that a drop occurred
|
||||||
|
testModel.composition.push('d');
|
||||||
|
mockScope.$on.mostRecentCall.args[1](
|
||||||
|
mockEvent,
|
||||||
|
'd',
|
||||||
|
{ x: 300, y: 100 }
|
||||||
|
);
|
||||||
|
mockScope.$watch.calls[0].args[1](['d']);
|
||||||
|
|
||||||
|
style = controller.getFrameStyle("d");
|
||||||
|
|
||||||
|
// Resulting size should still be reasonably large pixel-size
|
||||||
|
expect(parseInt(style.width, 10)).toBeGreaterThan(63);
|
||||||
|
expect(parseInt(style.height, 10)).toBeGreaterThan(31);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
ng-show="representation.showControls"
|
ng-show="representation.showControls"
|
||||||
ng-if="axes[1].options.length > 0">
|
ng-if="axes[1].options.length > 0">
|
||||||
<div class='form-control shell select'>
|
<div class='form-control shell select'>
|
||||||
<select class="form-control input shell select"
|
<select class="form-control input shell"
|
||||||
ng-model="axes[1].active"
|
ng-model="axes[1].active"
|
||||||
ng-options="option.name for option in axes[1].options">
|
ng-options="option.name for option in axes[1].options">
|
||||||
</select>
|
</select>
|
||||||
@ -160,12 +160,11 @@
|
|||||||
{{axes[0].active.name}}
|
{{axes[0].active.name}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="gl-plot-x-options gl-plot-local-controls"
|
<div class="gl-plot-x-options gl-plot-local-controls"
|
||||||
ng-show="representation.showControls"
|
ng-show="representation.showControls"
|
||||||
ng-if="axes[0].options.length > 0">
|
ng-if="axes[0].options.length > 0">
|
||||||
<div class='form-control shell select'>
|
<div class='form-control shell select'>
|
||||||
<select class="form-control input shell select"
|
<select class="form-control input shell"
|
||||||
ng-model="axes[0].active"
|
ng-model="axes[0].active"
|
||||||
ng-options="option.name for option in axes[0].options">
|
ng-options="option.name for option in axes[0].options">
|
||||||
</select>
|
</select>
|
||||||
|
@ -78,6 +78,8 @@ define(
|
|||||||
cachedObjects = [],
|
cachedObjects = [],
|
||||||
updater,
|
updater,
|
||||||
lastBounds,
|
lastBounds,
|
||||||
|
lastRange,
|
||||||
|
lastDomain,
|
||||||
handle;
|
handle;
|
||||||
|
|
||||||
// Populate the scope with axis information (specifically, options
|
// Populate the scope with axis information (specifically, options
|
||||||
@ -120,16 +122,16 @@ define(
|
|||||||
// Reinstantiate the plot updater (e.g. because we have a
|
// Reinstantiate the plot updater (e.g. because we have a
|
||||||
// new subscription.) This will clear the plot.
|
// new subscription.) This will clear the plot.
|
||||||
function recreateUpdater() {
|
function recreateUpdater() {
|
||||||
updater = new PlotUpdater(
|
var domain = $scope.axes[0].active.key,
|
||||||
handle,
|
range = $scope.axes[1].active.key,
|
||||||
($scope.axes[0].active || {}).key,
|
duration = PLOT_FIXED_DURATION;
|
||||||
($scope.axes[1].active || {}).key,
|
|
||||||
PLOT_FIXED_DURATION
|
updater = new PlotUpdater(handle, domain, range, duration);
|
||||||
);
|
lastDomain = domain;
|
||||||
self.limitTracker = new PlotLimitTracker(
|
lastRange = range;
|
||||||
handle,
|
|
||||||
($scope.axes[1].active || {}).key
|
self.limitTracker = new PlotLimitTracker(handle, range);
|
||||||
);
|
|
||||||
// Keep any externally-provided bounds
|
// Keep any externally-provided bounds
|
||||||
if (lastBounds) {
|
if (lastBounds) {
|
||||||
setBasePanZoom(lastBounds);
|
setBasePanZoom(lastBounds);
|
||||||
@ -201,22 +203,39 @@ define(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function requery() {
|
||||||
|
self.pending = true;
|
||||||
|
releaseSubscription();
|
||||||
|
subscribe($scope.domainObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateDomainFormat() {
|
||||||
|
var domainAxis = $scope.axes[0];
|
||||||
|
plotTelemetryFormatter
|
||||||
|
.setDomainFormat(domainAxis.active.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
function domainRequery(newDomain) {
|
||||||
|
if (newDomain !== lastDomain) {
|
||||||
|
updateDomainFormat();
|
||||||
|
requery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function rangeRequery(newRange) {
|
||||||
|
if (newRange !== lastRange) {
|
||||||
|
requery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Respond to a display bounds change (requery for data)
|
// Respond to a display bounds change (requery for data)
|
||||||
function changeDisplayBounds(event, bounds) {
|
function changeDisplayBounds(event, bounds) {
|
||||||
var domainAxis = $scope.axes[0];
|
var domainAxis = $scope.axes[0];
|
||||||
|
|
||||||
domainAxis.chooseOption(bounds.domain);
|
domainAxis.chooseOption(bounds.domain);
|
||||||
plotTelemetryFormatter
|
updateDomainFormat();
|
||||||
.setDomainFormat(domainAxis.active.format);
|
|
||||||
|
|
||||||
self.pending = true;
|
|
||||||
releaseSubscription();
|
|
||||||
subscribe($scope.domainObject);
|
|
||||||
setBasePanZoom(bounds);
|
setBasePanZoom(bounds);
|
||||||
}
|
requery();
|
||||||
|
|
||||||
function updateDomainFormat(format) {
|
|
||||||
plotTelemetryFormatter.setDomainFormat(format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.modeOptions = new PlotModeOptions([], subPlotFactory);
|
this.modeOptions = new PlotModeOptions([], subPlotFactory);
|
||||||
@ -237,6 +256,10 @@ define(
|
|||||||
new PlotAxis("ranges", [], AXIS_DEFAULTS[1])
|
new PlotAxis("ranges", [], AXIS_DEFAULTS[1])
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Watch for changes to the selected axis
|
||||||
|
$scope.$watch("axes[0].active.key", domainRequery);
|
||||||
|
$scope.$watch("axes[1].active.key", rangeRequery);
|
||||||
|
|
||||||
// Subscribe to telemetry when a domain object becomes available
|
// Subscribe to telemetry when a domain object becomes available
|
||||||
$scope.$watch('domainObject', subscribe);
|
$scope.$watch('domainObject', subscribe);
|
||||||
|
|
||||||
|
@ -53,6 +53,14 @@ define(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fireWatch(expr, value) {
|
||||||
|
mockScope.$watch.calls.forEach(function (call) {
|
||||||
|
if (call.args[0] === expr) {
|
||||||
|
call.args[1].apply(null, [value]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
mockScope = jasmine.createSpyObj(
|
mockScope = jasmine.createSpyObj(
|
||||||
@ -263,6 +271,20 @@ define(
|
|||||||
]);
|
]);
|
||||||
expect(mockHandle.request.calls.length).toEqual(2);
|
expect(mockHandle.request.calls.length).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("requeries when user changes domain selection", function () {
|
||||||
|
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
|
||||||
|
expect(mockHandle.request.calls.length).toEqual(1);
|
||||||
|
fireWatch("axes[0].active.key", 'someNewKey');
|
||||||
|
expect(mockHandle.request.calls.length).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("requeries when user changes range selection", function () {
|
||||||
|
mockScope.$watch.mostRecentCall.args[1](mockDomainObject);
|
||||||
|
expect(mockHandle.request.calls.length).toEqual(1);
|
||||||
|
fireWatch("axes[1].active.key", 'someNewKey');
|
||||||
|
expect(mockHandle.request.calls.length).toEqual(2);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -19,40 +19,17 @@
|
|||||||
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 class="search"
|
<div class="l-flex-col flex-elem grows holder holder-search" ng-controller="SearchController as controller">
|
||||||
ng-controller="SearchController as controller">
|
<div class="search-bar flex-elem" ng-controller="ClickAwayController as toggle">
|
||||||
|
|
||||||
<!-- Search bar -->
|
|
||||||
<div class="search-bar"
|
|
||||||
ng-controller="ClickAwayController as toggle">
|
|
||||||
|
|
||||||
<!-- Input field -->
|
|
||||||
<input class="search-input"
|
<input class="search-input"
|
||||||
type="text"
|
type="text"
|
||||||
ng-model="ngModel.input"
|
ng-model="ngModel.input"
|
||||||
ng-keyup="controller.search()" />
|
ng-keyup="controller.search()" />
|
||||||
|
<a class="clear-icon"
|
||||||
<!-- Search icon -->
|
ng-class="{show: !(ngModel.input === '' || ngModel.input === undefined)}"
|
||||||
<!-- ui symbols for search are 'd' and 'M' -->
|
ng-click="ngModel.input = ''; controller.search()"></a>
|
||||||
<div class="ui-symbol search-icon"
|
<a class="menu-icon"
|
||||||
ng-class="{content: !(ngModel.input === '' || ngModel.input === undefined)}">
|
ng-click="toggle.toggle()"></a>
|
||||||
M
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Clear icon/button 'x' -->
|
|
||||||
<a class="ui-symbol clear-icon"
|
|
||||||
ng-class="{content: !(ngModel.input === '' || ngModel.input === undefined)}"
|
|
||||||
ng-click="ngModel.input = ''; controller.search()">
|
|
||||||

|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- Menu icon/button 'v' -->
|
|
||||||
<a class="ui-symbol menu-icon"
|
|
||||||
ng-click="toggle.toggle()">
|
|
||||||
v
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<!-- Menu -->
|
|
||||||
<mct-include key="'search-menu'"
|
<mct-include key="'search-menu'"
|
||||||
class="menu-element search-menu-holder"
|
class="menu-element search-menu-holder"
|
||||||
ng-class="{off: !toggle.isActive()}"
|
ng-class="{off: !toggle.isActive()}"
|
||||||
@ -60,49 +37,20 @@
|
|||||||
ng-click="toggle.setState(true)">
|
ng-click="toggle.setState(true)">
|
||||||
</mct-include>
|
</mct-include>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="active-filter-display flex-elem"
|
||||||
<!-- Active filter display -->
|
|
||||||
<div class="active-filter-display"
|
|
||||||
ng-class="{off: ngModel.filtersString === '' || ngModel.filtersString === undefined || !ngModel.search}"
|
ng-class="{off: ngModel.filtersString === '' || ngModel.filtersString === undefined || !ngModel.search}"
|
||||||
ng-controller="SearchMenuController as menuController">
|
ng-controller="SearchMenuController as menuController">
|
||||||
|
<a class="clear-icon clear-filters-icon"
|
||||||
<a class="ui-symbol clear-filters-icon"
|
ng-click="ngModel.checkAll = true; menuController.checkAll()"></a>Filtered by: {{ ngModel.filtersString }}
|
||||||
ng-click="ngModel.checkAll = true; menuController.checkAll()">
|
|
||||||

|
|
||||||
</a>
|
|
||||||
|
|
||||||
Filtered by: {{ ngModel.filtersString }}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="search-results flex-elem grows vscroll"
|
||||||
<!-- This div exists to determine scroll bar location -->
|
ng-class="{ off: !(loading || results.length > 0), loading: loading }">
|
||||||
<div class="search-scroll abs">
|
|
||||||
|
|
||||||
<!-- Results list -->
|
|
||||||
<div class="results">
|
|
||||||
<mct-representation key="'search-item'"
|
<mct-representation key="'search-item'"
|
||||||
ng-repeat="result in results"
|
ng-repeat="result in results"
|
||||||
mct-object="result.object"
|
mct-object="result.object"
|
||||||
ng-model="ngModel">
|
ng-model="ngModel">
|
||||||
</mct-representation>
|
</mct-representation>
|
||||||
</div>
|
<a class="load-more-button s-btn vsm" ng-if="controller.areMore()" ng-click="controller.loadMore()">More Results</a>
|
||||||
|
|
||||||
<!-- Loading icon -->
|
|
||||||
<div class="load-icon"
|
|
||||||
ng-class="{loading: loading}"
|
|
||||||
ng-if="loading">
|
|
||||||
<span class="icon wait-spinner"></span>
|
|
||||||
<span class="title-label">Loading...</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Load more button -->
|
|
||||||
<div ng-if="controller.areMore()">
|
|
||||||
<a class="load-more-button s-btn vsm"
|
|
||||||
ng-click="controller.loadMore()">
|
|
||||||
More Results
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
2
platform/status/README.md
Normal file
2
platform/status/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Facilitates tracking states associated with specific domain
|
||||||
|
objects.
|
23
platform/status/bundle.json
Normal file
23
platform/status/bundle.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"representers": [
|
||||||
|
{
|
||||||
|
"implementation": "StatusRepresenter.js"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"capabilities": [
|
||||||
|
{
|
||||||
|
"key": "status",
|
||||||
|
"implementation": "StatusCapability.js",
|
||||||
|
"depends": [ "statusService" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": [
|
||||||
|
{
|
||||||
|
"key": "statusService",
|
||||||
|
"implementation": "StatusService.js",
|
||||||
|
"depends": [ "topic" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
100
platform/status/src/StatusCapability.js
Normal file
100
platform/status/src/StatusCapability.js
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `status` capability can be used to attach information
|
||||||
|
* about the state of a domain object, expressed as simple
|
||||||
|
* string flags.
|
||||||
|
*
|
||||||
|
* Representations of domain objects will also receive CSS
|
||||||
|
* classes which reflect their current status.
|
||||||
|
* (@see platform/status.StatusRepresenter)
|
||||||
|
*
|
||||||
|
* @param {platform/status.StatusService} statusService
|
||||||
|
* the service which will track domain object status
|
||||||
|
* within the application.
|
||||||
|
* @param {DomainObject} the domain object whose status will
|
||||||
|
* be tracked.
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/status
|
||||||
|
*/
|
||||||
|
function StatusCapability(statusService, domainObject) {
|
||||||
|
this.statusService = statusService;
|
||||||
|
this.domainObject = domainObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List all status flags currently set for this domain object.
|
||||||
|
* @returns {string[]} all current status flags.
|
||||||
|
*/
|
||||||
|
StatusCapability.prototype.list = function () {
|
||||||
|
return this.statusService.listStatuses(this.domainObject.getId());
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a status flag is currently set for this domain object.
|
||||||
|
* @param {string} status the status to get
|
||||||
|
* @returns {boolean} true if the flag is present, otherwise false
|
||||||
|
*/
|
||||||
|
StatusCapability.prototype.get = function (status) {
|
||||||
|
return this.list().indexOf(status) !== -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a status flag on this domain object.
|
||||||
|
* @param {string} status the status to set
|
||||||
|
* @param {boolean} state true if the domain object should
|
||||||
|
* possess this status, false if it should not
|
||||||
|
*/
|
||||||
|
StatusCapability.prototype.set = function (status, state) {
|
||||||
|
return this.statusService.setStatus(
|
||||||
|
this.domainObject.getId(),
|
||||||
|
status,
|
||||||
|
state
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for changes in this domain object's status.
|
||||||
|
* @param {Function} callback function to invoke on changes;
|
||||||
|
* called with the new status of the domain object, as an
|
||||||
|
* array of strings
|
||||||
|
* @returns {Function} a function which can be used to stop
|
||||||
|
* listening to status changes for this domain object.
|
||||||
|
*/
|
||||||
|
StatusCapability.prototype.listen = function (callback) {
|
||||||
|
return this.statusService.listen(
|
||||||
|
this.domainObject.getId(),
|
||||||
|
callback
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return StatusCapability;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
26
platform/status/src/StatusConstants.js
Normal file
26
platform/status/src/StatusConstants.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
define({
|
||||||
|
CSS_CLASS_PREFIX: 's-status-',
|
||||||
|
TOPIC_PREFIX: 'status:'
|
||||||
|
});
|
96
platform/status/src/StatusRepresenter.js
Normal file
96
platform/status/src/StatusRepresenter.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['./StatusConstants'],
|
||||||
|
function (StatusConstants) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var STATUS_CLASS_PREFIX = StatusConstants.CSS_CLASS_PREFIX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds/removes CSS classes to `mct-representation`s to reflect the
|
||||||
|
* current status of represented domain objects, as reported by
|
||||||
|
* their `status` capability.
|
||||||
|
*
|
||||||
|
* Statuses are prefixed with `s-status-` to build CSS class names.
|
||||||
|
* As such, when a domain object has the status "pending", its
|
||||||
|
* representations will have the CSS class `s-status-pending`.
|
||||||
|
*
|
||||||
|
* @param {angular.Scope} scope the representation's scope object
|
||||||
|
* @param element the representation's jqLite-wrapped DOM element
|
||||||
|
* @implements {Representer}
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/status
|
||||||
|
*/
|
||||||
|
function StatusRepresenter(scope, element) {
|
||||||
|
this.element = element;
|
||||||
|
this.lastClasses = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove any status-related classes from this representation.
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
StatusRepresenter.prototype.clearClasses = function () {
|
||||||
|
var element = this.element;
|
||||||
|
this.lastClasses.forEach(function (c) {
|
||||||
|
element.removeClass(c);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
StatusRepresenter.prototype.represent = function (representation, domainObject) {
|
||||||
|
var self = this,
|
||||||
|
statusCapability = domainObject.getCapability('status');
|
||||||
|
|
||||||
|
function updateStatus(flags) {
|
||||||
|
var newClasses = flags.map(function (flag) {
|
||||||
|
return STATUS_CLASS_PREFIX + flag;
|
||||||
|
});
|
||||||
|
|
||||||
|
self.clearClasses();
|
||||||
|
|
||||||
|
newClasses.forEach(function (c) {
|
||||||
|
self.element.addClass(c);
|
||||||
|
});
|
||||||
|
|
||||||
|
self.lastClasses = newClasses;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStatus(statusCapability.list());
|
||||||
|
this.unlisten = statusCapability.listen(updateStatus);
|
||||||
|
};
|
||||||
|
|
||||||
|
StatusRepresenter.prototype.destroy = function () {
|
||||||
|
this.clearClasses();
|
||||||
|
if (this.unlisten) {
|
||||||
|
this.unlisten();
|
||||||
|
this.unlisten = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return StatusRepresenter;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
92
platform/status/src/StatusService.js
Normal file
92
platform/status/src/StatusService.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['./StatusConstants'],
|
||||||
|
function (StatusConstants) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var STATUS_PREFIX = StatusConstants.TOPIC_PREFIX;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The `statusService` maintains information about the current
|
||||||
|
* status of specific domain objects within the system. Status
|
||||||
|
* is represented as string flags which are present when a
|
||||||
|
* domain object possesses that status, and false when it does
|
||||||
|
* not.
|
||||||
|
*
|
||||||
|
* @param {platform/core.Topic} topic the `topic` service, used
|
||||||
|
* to create/use named listeners.
|
||||||
|
* @constructor
|
||||||
|
* @memberof platform/status
|
||||||
|
*/
|
||||||
|
function StatusService(topic) {
|
||||||
|
this.statusTable = {};
|
||||||
|
this.topic = topic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all status flags currently set for a domain object.
|
||||||
|
* @param {string} id the identifier of the domain object
|
||||||
|
* @returns {string[]} an array containing all status flags currently
|
||||||
|
* applicable to the object with this identifier
|
||||||
|
*/
|
||||||
|
StatusService.prototype.listStatuses = function (id) {
|
||||||
|
return this.statusTable[id] || [];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a status flag for a domain object.
|
||||||
|
* @param {string} id the identifier of the domain object
|
||||||
|
* @param {string} status the status to set
|
||||||
|
* @param {boolean} state true if the domain object should
|
||||||
|
* possess this status, false if it should not
|
||||||
|
*/
|
||||||
|
StatusService.prototype.setStatus = function (id, status, state) {
|
||||||
|
this.statusTable[id] = this.statusTable[id] || [];
|
||||||
|
this.statusTable[id] = this.statusTable[id].filter(function (s) {
|
||||||
|
return s !== status;
|
||||||
|
});
|
||||||
|
if (state) {
|
||||||
|
this.statusTable[id].push(status);
|
||||||
|
}
|
||||||
|
this.topic(STATUS_PREFIX + id).notify(this.statusTable[id]);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listen for changes in a domain object's status.
|
||||||
|
* @param {string} id the identifier of the domain object
|
||||||
|
* @param {Function} callback function to invoke on changes;
|
||||||
|
* called with the new status of the domain object, as an
|
||||||
|
* array of strings
|
||||||
|
* @returns {Function} a function which can be used to stop
|
||||||
|
* listening to status changes for this domain object.
|
||||||
|
*/
|
||||||
|
StatusService.prototype.listen = function (id, callback) {
|
||||||
|
return this.topic(STATUS_PREFIX + id).listen(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
return StatusService;
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
89
platform/status/test/StatusCapabilitySpec.js
Normal file
89
platform/status/test/StatusCapabilitySpec.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../src/StatusCapability"],
|
||||||
|
function (StatusCapability) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The status capability", function () {
|
||||||
|
var mockStatusService,
|
||||||
|
mockDomainObject,
|
||||||
|
mockUnlisten,
|
||||||
|
testId,
|
||||||
|
testStatusFlags,
|
||||||
|
capability;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
testId = "some-id";
|
||||||
|
testStatusFlags = [ 'a', 'b', 'c' ];
|
||||||
|
|
||||||
|
mockStatusService = jasmine.createSpyObj(
|
||||||
|
'statusService',
|
||||||
|
[ 'listen', 'setStatus', 'listStatuses' ]
|
||||||
|
);
|
||||||
|
mockDomainObject = jasmine.createSpyObj(
|
||||||
|
'domainObject',
|
||||||
|
[ 'getId', 'getCapability', 'getModel' ]
|
||||||
|
);
|
||||||
|
mockUnlisten = jasmine.createSpy('unlisten');
|
||||||
|
|
||||||
|
mockStatusService.listen.andReturn(mockUnlisten);
|
||||||
|
mockStatusService.listStatuses.andReturn(testStatusFlags);
|
||||||
|
mockDomainObject.getId.andReturn(testId);
|
||||||
|
|
||||||
|
capability = new StatusCapability(
|
||||||
|
mockStatusService,
|
||||||
|
mockDomainObject
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("sets status with the statusService", function () {
|
||||||
|
var testStatus = "some-test-status";
|
||||||
|
capability.set(testStatus, true);
|
||||||
|
expect(mockStatusService.setStatus)
|
||||||
|
.toHaveBeenCalledWith(testId, testStatus, true);
|
||||||
|
capability.set(testStatus, false);
|
||||||
|
expect(mockStatusService.setStatus)
|
||||||
|
.toHaveBeenCalledWith(testId, testStatus, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("gets status from the statusService", function () {
|
||||||
|
expect(capability.list()).toBe(testStatusFlags);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("listens to changes from the statusService", function () {
|
||||||
|
var mockCallback = jasmine.createSpy();
|
||||||
|
expect(capability.listen(mockCallback))
|
||||||
|
.toBe(mockUnlisten);
|
||||||
|
expect(mockStatusService.listen)
|
||||||
|
.toHaveBeenCalledWith(testId, mockCallback);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows statuses to be checked individually", function () {
|
||||||
|
expect(capability.get('some-unset-status')).toBe(false);
|
||||||
|
expect(capability.get(testStatusFlags[0])).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
118
platform/status/test/StatusRepresenterSpec.js
Normal file
118
platform/status/test/StatusRepresenterSpec.js
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../src/StatusRepresenter", "../src/StatusConstants"],
|
||||||
|
function (StatusRepresenter, StatusConstants) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The status representer", function () {
|
||||||
|
var mockScope,
|
||||||
|
mockElement,
|
||||||
|
testRepresentation,
|
||||||
|
mockDomainObject,
|
||||||
|
mockStatusCapability,
|
||||||
|
mockUnlisten,
|
||||||
|
elementClasses,
|
||||||
|
testStatusFlags,
|
||||||
|
representer;
|
||||||
|
|
||||||
|
function verifyClasses() {
|
||||||
|
expect(Object.keys(elementClasses).sort())
|
||||||
|
.toEqual(testStatusFlags.map(function (s) {
|
||||||
|
return StatusConstants.CSS_CLASS_PREFIX + s;
|
||||||
|
}).sort());
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateStatus(newFlags) {
|
||||||
|
testStatusFlags = newFlags;
|
||||||
|
mockStatusCapability.get.andReturn(newFlags);
|
||||||
|
mockStatusCapability.listen.mostRecentCall
|
||||||
|
.args[0](newFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
testStatusFlags = [ 'x', 'y', 'z' ];
|
||||||
|
|
||||||
|
mockScope = {};
|
||||||
|
mockElement = jasmine.createSpyObj('element', [
|
||||||
|
'addClass',
|
||||||
|
'removeClass'
|
||||||
|
]);
|
||||||
|
testRepresentation = { key: "someKey" };
|
||||||
|
mockDomainObject = jasmine.createSpyObj(
|
||||||
|
'domainObject',
|
||||||
|
[ 'getModel', 'getId', 'getCapability' ]
|
||||||
|
);
|
||||||
|
mockStatusCapability = jasmine.createSpyObj(
|
||||||
|
'status',
|
||||||
|
[ 'list', 'get', 'set', 'listen' ]
|
||||||
|
);
|
||||||
|
mockUnlisten = jasmine.createSpy();
|
||||||
|
|
||||||
|
elementClasses = {};
|
||||||
|
|
||||||
|
mockElement.addClass.andCallFake(function (c) {
|
||||||
|
elementClasses[c] = true;
|
||||||
|
});
|
||||||
|
mockElement.removeClass.andCallFake(function (c) {
|
||||||
|
delete elementClasses[c];
|
||||||
|
});
|
||||||
|
|
||||||
|
mockStatusCapability.list.andReturn(testStatusFlags);
|
||||||
|
mockStatusCapability.listen.andReturn(mockUnlisten);
|
||||||
|
|
||||||
|
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||||
|
return c === 'status' && mockStatusCapability;
|
||||||
|
});
|
||||||
|
|
||||||
|
representer = new StatusRepresenter(mockScope, mockElement);
|
||||||
|
representer.represent(testRepresentation, mockDomainObject);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("listens for status changes", function () {
|
||||||
|
expect(mockStatusCapability.listen)
|
||||||
|
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("initially sets classes to reflect status", verifyClasses);
|
||||||
|
|
||||||
|
it("changes classes on status change callbacks", function () {
|
||||||
|
updateStatus(['a', 'x', '123']);
|
||||||
|
verifyClasses();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("stops listening when destroyed", function () {
|
||||||
|
expect(mockUnlisten).not.toHaveBeenCalled();
|
||||||
|
representer.destroy();
|
||||||
|
expect(mockUnlisten).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("removes status classes when destroyed", function () {
|
||||||
|
expect(elementClasses).not.toEqual({});
|
||||||
|
representer.destroy();
|
||||||
|
expect(elementClasses).toEqual({});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
94
platform/status/test/StatusServiceSpec.js
Normal file
94
platform/status/test/StatusServiceSpec.js
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT Web 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 Web 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
/*global define,Promise,describe,it,expect,beforeEach,waitsFor,jasmine*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
["../src/StatusService"],
|
||||||
|
function (StatusService) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
describe("The status service", function () {
|
||||||
|
var mockTopic,
|
||||||
|
mockTopicInstance,
|
||||||
|
mockUnlisten,
|
||||||
|
mockCallback,
|
||||||
|
testId,
|
||||||
|
testStatus,
|
||||||
|
statusService;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
testId = "some-domain-object-identifier";
|
||||||
|
testStatus = "test-status";
|
||||||
|
|
||||||
|
mockTopic = jasmine.createSpy('topic');
|
||||||
|
mockTopicInstance = jasmine.createSpyObj(
|
||||||
|
'topicInstance',
|
||||||
|
[ 'notify', 'listen' ]
|
||||||
|
);
|
||||||
|
mockUnlisten = jasmine.createSpy('unlisten');
|
||||||
|
mockCallback = jasmine.createSpy('callback');
|
||||||
|
|
||||||
|
mockTopic.andReturn(mockTopicInstance);
|
||||||
|
mockTopicInstance.listen.andReturn(mockUnlisten);
|
||||||
|
|
||||||
|
statusService = new StatusService(mockTopic);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("initially contains no flags for an object", function () {
|
||||||
|
expect(statusService.listStatuses(testId)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("stores and clears status flags", function () {
|
||||||
|
statusService.setStatus(testId, testStatus, true);
|
||||||
|
expect(statusService.listStatuses(testId)).toEqual([testStatus]);
|
||||||
|
statusService.setStatus(testId, testStatus, false);
|
||||||
|
expect(statusService.listStatuses(testId)).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses topic to listen for changes", function () {
|
||||||
|
expect(statusService.listen(testId, mockCallback))
|
||||||
|
.toEqual(mockUnlisten);
|
||||||
|
expect(mockTopic)
|
||||||
|
.toHaveBeenCalledWith(jasmine.any(String));
|
||||||
|
// Just care that the topic was somehow unique to the object
|
||||||
|
expect(mockTopic.mostRecentCall.args[0].indexOf(testId))
|
||||||
|
.not.toEqual(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("notifies listeners of changes", function () {
|
||||||
|
statusService.setStatus(testId, testStatus, true);
|
||||||
|
expect(mockTopicInstance.notify)
|
||||||
|
.toHaveBeenCalledWith([ testStatus ]);
|
||||||
|
statusService.setStatus(testId, testStatus, false);
|
||||||
|
expect(mockTopicInstance.notify)
|
||||||
|
.toHaveBeenCalledWith([ ]);
|
||||||
|
|
||||||
|
expect(mockTopic)
|
||||||
|
.toHaveBeenCalledWith(jasmine.any(String));
|
||||||
|
// Just care that the topic was somehow unique to the object
|
||||||
|
expect(mockTopic.mostRecentCall.args[0].indexOf(testId))
|
||||||
|
.not.toEqual(-1);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
5
platform/status/test/suite.json
Normal file
5
platform/status/test/suite.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[
|
||||||
|
"StatusCapability",
|
||||||
|
"StatusRepresenter",
|
||||||
|
"StatusService"
|
||||||
|
]
|
@ -285,11 +285,17 @@ define(
|
|||||||
* domain objects returned by `getTelemetryObjects()`.
|
* domain objects returned by `getTelemetryObjects()`.
|
||||||
*
|
*
|
||||||
* @param {DomainObject} domainObject the object of interest
|
* @param {DomainObject} domainObject the object of interest
|
||||||
|
* @param {string} [key] the symbolic identifier of the domain
|
||||||
|
* to look up; if omitted, the value for this object's
|
||||||
|
* default domain will be used
|
||||||
* @returns the most recent domain value observed
|
* @returns the most recent domain value observed
|
||||||
*/
|
*/
|
||||||
TelemetrySubscription.prototype.getDomainValue = function (domainObject) {
|
TelemetrySubscription.prototype.getDomainValue = function (domainObject, key) {
|
||||||
var id = domainObject.getId();
|
var id = domainObject.getId(),
|
||||||
return (this.latestValues[id] || {}).domain;
|
latestValue = this.latestValues[id];
|
||||||
|
return latestValue && (key ?
|
||||||
|
latestValue.datum[key] :
|
||||||
|
latestValue.domain);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -302,11 +308,17 @@ define(
|
|||||||
* domain objects returned by `getTelemetryObjects()`.
|
* domain objects returned by `getTelemetryObjects()`.
|
||||||
*
|
*
|
||||||
* @param {DomainObject} domainObject the object of interest
|
* @param {DomainObject} domainObject the object of interest
|
||||||
|
* @param {string} [key] the symbolic identifier of the range
|
||||||
|
* to look up; if omitted, the value for this object's
|
||||||
|
* default range will be used
|
||||||
* @returns the most recent range value observed
|
* @returns the most recent range value observed
|
||||||
*/
|
*/
|
||||||
TelemetrySubscription.prototype.getRangeValue = function (domainObject) {
|
TelemetrySubscription.prototype.getRangeValue = function (domainObject, key) {
|
||||||
var id = domainObject.getId();
|
var id = domainObject.getId(),
|
||||||
return (this.latestValues[id] || {}).range;
|
latestValue = this.latestValues[id];
|
||||||
|
return latestValue && (key ?
|
||||||
|
latestValue.datum[key] :
|
||||||
|
latestValue.range);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user