mirror of
https://github.com/nasa/openmct.git
synced 2024-12-24 15:26:39 +00:00
parent
c5187d8509
commit
944505a5f1
2
app.js
2
app.js
@ -16,7 +16,7 @@ const request = require('request');
|
|||||||
|
|
||||||
// Defaults
|
// Defaults
|
||||||
options.port = options.port || options.p || 8080;
|
options.port = options.port || options.p || 8080;
|
||||||
options.host = options.host || options.h || 'localhost'
|
options.host = options.host || options.h || 'localhost';
|
||||||
options.directory = options.directory || options.D || '.';
|
options.directory = options.directory || options.D || '.';
|
||||||
|
|
||||||
// Show command line options
|
// Show command line options
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
}));
|
}));
|
||||||
openmct.install(openmct.plugins.SummaryWidget());
|
openmct.install(openmct.plugins.SummaryWidget());
|
||||||
openmct.install(openmct.plugins.Notebook());
|
openmct.install(openmct.plugins.Notebook());
|
||||||
|
openmct.install(openmct.plugins.FolderView());
|
||||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
||||||
openmct.time.timeSystem('utc');
|
openmct.time.timeSystem('utc');
|
||||||
openmct.start();
|
openmct.start();
|
||||||
|
67
src/plugins/folderView/FolderGridView.js
Normal file
67
src/plugins/folderView/FolderGridView.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./components/GridView.vue',
|
||||||
|
'vue'
|
||||||
|
], function (
|
||||||
|
GridViewComponent,
|
||||||
|
Vue
|
||||||
|
) {
|
||||||
|
function FolderGridView(openmct) {
|
||||||
|
return {
|
||||||
|
key: 'grid',
|
||||||
|
name: 'Grid Vue',
|
||||||
|
cssClass: 'icon-thumbs-strip',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'folder';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let component;
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: function (element) {
|
||||||
|
component = new Vue({
|
||||||
|
components: {
|
||||||
|
gridViewComponent: GridViewComponent.default
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
openmct,
|
||||||
|
domainObject
|
||||||
|
},
|
||||||
|
el: element,
|
||||||
|
template: '<grid-view-component></grid-view-component>'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function (element) {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority: function () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return FolderGridView;
|
||||||
|
});
|
70
src/plugins/folderView/FolderListView.js
Normal file
70
src/plugins/folderView/FolderListView.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./components/ListView.vue',
|
||||||
|
'vue',
|
||||||
|
'moment'
|
||||||
|
], function (
|
||||||
|
ListViewComponent,
|
||||||
|
Vue,
|
||||||
|
Moment
|
||||||
|
) {
|
||||||
|
function FolderListView(openmct) {
|
||||||
|
return {
|
||||||
|
key: 'list-view',
|
||||||
|
name: 'List Vue',
|
||||||
|
cssClass: 'icon-list-view',
|
||||||
|
canView: function (domainObject) {
|
||||||
|
return domainObject.type === 'folder';
|
||||||
|
},
|
||||||
|
view: function (domainObject) {
|
||||||
|
let component;
|
||||||
|
|
||||||
|
return {
|
||||||
|
show: function (element) {
|
||||||
|
component = new Vue({
|
||||||
|
components: {
|
||||||
|
listViewComponent: ListViewComponent.default
|
||||||
|
},
|
||||||
|
provide: {
|
||||||
|
openmct,
|
||||||
|
domainObject,
|
||||||
|
Moment
|
||||||
|
},
|
||||||
|
el: element,
|
||||||
|
template: '<list-view-component></list-view-component>'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
destroy: function (element) {
|
||||||
|
component.$destroy();
|
||||||
|
component = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
priority: function () {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return FolderListView;
|
||||||
|
});
|
207
src/plugins/folderView/components/GridView.vue
Normal file
207
src/plugins/folderView/components/GridView.vue
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
<template>
|
||||||
|
<div class="l-grid-view">
|
||||||
|
<div v-for="(item, index) in items"
|
||||||
|
v-bind:key="index"
|
||||||
|
class="l-grid-view__item c-grid-item"
|
||||||
|
:class="{ 'is-alias': item.isAlias === true }"
|
||||||
|
@click="navigate(item.model.identifier.key)">
|
||||||
|
<div class="c-grid-item__type-icon"
|
||||||
|
:class="(item.type.cssClass != undefined) ? 'bg-' + item.type.cssClass : 'bg-icon-object-unknown'">
|
||||||
|
</div>
|
||||||
|
<div class="c-grid-item__details">
|
||||||
|
<!-- Name and metadata -->
|
||||||
|
<div class="c-grid-item__name"
|
||||||
|
:title="item.model.name">{{item.model.name}}</div>
|
||||||
|
<div class="c-grid-item__metadata"
|
||||||
|
:title="item.type.name">
|
||||||
|
<span>{{item.type.name}}</span>
|
||||||
|
<span v-if="item.model.composition !== undefined">
|
||||||
|
- {{item.model.composition.length}} item<span v-if="item.model.composition.length !== 1">s</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-grid-item__controls">
|
||||||
|
<div class="icon-people" title='Shared'></div>
|
||||||
|
<div class="c-icon-button icon-info c-info-button" title='More Info'></div>
|
||||||
|
<div class="icon-pointer-right c-pointer-icon"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
/******************************* GRID VIEW */
|
||||||
|
.l-grid-view {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
|
||||||
|
&__item {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
+ .l-grid-view__item { margin-top: $interiorMargin; }
|
||||||
|
}
|
||||||
|
|
||||||
|
body.desktop & {
|
||||||
|
flex-flow: row wrap;
|
||||||
|
&__item {
|
||||||
|
height: $ueBrowseGridItemLg;
|
||||||
|
width: $ueBrowseGridItemLg;
|
||||||
|
margin: 0 $interiorMargin $interiorMargin 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************* GRID ITEMS */
|
||||||
|
.c-grid-item {
|
||||||
|
// Mobile-first
|
||||||
|
@include button($bg: $colorItemBg, $fg: $colorItemFg);
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
padding: $interiorMarginLg;
|
||||||
|
|
||||||
|
&__type-icon {
|
||||||
|
filter: $colorKeyFilter;
|
||||||
|
flex: 0 0 32px;
|
||||||
|
margin-right: $interiorMarginLg;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-alias {
|
||||||
|
// Object is an alias to an original.
|
||||||
|
[class*='__type-icon'] {
|
||||||
|
&:before {
|
||||||
|
color: $colorIconAliasForKeyFilter;
|
||||||
|
content: $glyph-icon-link;
|
||||||
|
display: block;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 2.5em;
|
||||||
|
position: absolute;
|
||||||
|
text-shadow: rgba(black, 0.5) 0 1px 4px;
|
||||||
|
top: auto; left: 0; bottom: 10px; right: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__details {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__name {
|
||||||
|
@include ellipsize();
|
||||||
|
color: $colorItemFg;
|
||||||
|
font-size: 1.3em;
|
||||||
|
font-weight: 400;
|
||||||
|
margin-bottom: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__metadata {
|
||||||
|
color: $colorItemFgDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__controls {
|
||||||
|
color: $colorItemFgDetails;
|
||||||
|
flex: 0 0 64px;
|
||||||
|
font-size: 1.2em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
|
||||||
|
> * + * {
|
||||||
|
margin-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
body.desktop & {
|
||||||
|
$transOutMs: 300ms;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
transition: background $transOutMs ease-in-out;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $colorItemBgHov;
|
||||||
|
transition: $transIn;
|
||||||
|
|
||||||
|
.c-grid-item__type-icon {
|
||||||
|
filter: $colorKeyFilterHov;
|
||||||
|
transform: scale(1);
|
||||||
|
transition: $transInBounce;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> * {
|
||||||
|
margin: 0; // Reset from mobile
|
||||||
|
}
|
||||||
|
|
||||||
|
&__controls {
|
||||||
|
align-items: start;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
order: 1;
|
||||||
|
.c-info-button,
|
||||||
|
.c-pointer-icon { display: none; }
|
||||||
|
}
|
||||||
|
|
||||||
|
&__type-icon {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
margin: $interiorMargin 22.5%;
|
||||||
|
order: 2;
|
||||||
|
transform: scale(0.9);
|
||||||
|
transform-origin: center;
|
||||||
|
transition: all $transOutMs ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__details {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
justify-content: flex-end;
|
||||||
|
order: 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
inject: ['openmct', 'domainObject'],
|
||||||
|
data() {
|
||||||
|
var items = [],
|
||||||
|
unknownObjectType = {
|
||||||
|
definition: {
|
||||||
|
cssClass: 'icon-object-unknown',
|
||||||
|
name: 'Unknown Type'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
|
||||||
|
if (composition) {
|
||||||
|
|
||||||
|
composition.load().then((array) => {
|
||||||
|
if (Array.isArray(array)) {
|
||||||
|
array.forEach((model) => {
|
||||||
|
var type = this.openmct.types.get(model.type) || unknownObjectType;
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
model: model,
|
||||||
|
type: type.definition,
|
||||||
|
isAlias: this.domainObject.identifier.key !== model.location
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {
|
||||||
|
items: items
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
navigate(identifier) {
|
||||||
|
let currentLocation = this.openmct.router.currentLocation.path,
|
||||||
|
navigateToPath = `${currentLocation}/${identifier}`;
|
||||||
|
|
||||||
|
this.openmct.router.setPath(navigateToPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
215
src/plugins/folderView/components/ListView.vue
Normal file
215
src/plugins/folderView/components/ListView.vue
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-table c-table--sortable c-list-view">
|
||||||
|
<table class="c-table__body">
|
||||||
|
<thead class="c-table__header">
|
||||||
|
<tr>
|
||||||
|
<th class="is-sortable"
|
||||||
|
v-bind:class="[orderByField == 'name' ? 'is-sorting' : '', sortClass]"
|
||||||
|
@click="sortTrigger('name', 'asc')">
|
||||||
|
Name
|
||||||
|
</th>
|
||||||
|
<th class="is-sortable"
|
||||||
|
v-bind:class="[orderByField == 'type' ? 'is-sorting' : '', sortClass]"
|
||||||
|
@click="sortTrigger('type', 'asc')">
|
||||||
|
Type
|
||||||
|
</th>
|
||||||
|
<th class="is-sortable"
|
||||||
|
v-bind:class="[orderByField == 'createdDate' ? 'is-sorting' : '', sortClass]"
|
||||||
|
@click="sortTrigger('createdDate', 'desc')">
|
||||||
|
Created Date
|
||||||
|
</th>
|
||||||
|
<th class="is-sortable"
|
||||||
|
v-bind:class="[orderByField == 'updatedDate' ? 'is-sorting' : '', sortClass]"
|
||||||
|
@click="sortTrigger('updatedDate', 'desc')">
|
||||||
|
Updated Date
|
||||||
|
</th>
|
||||||
|
<th class="is-sortable"
|
||||||
|
v-bind:class="[orderByField == 'items' ? 'is-sorting' : '', sortClass]"
|
||||||
|
@click="sortTrigger('items', 'asc')">
|
||||||
|
Items
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr class="c-list-item"
|
||||||
|
v-for="(item,index) in sortedItems"
|
||||||
|
v-bind:key="index"
|
||||||
|
:class="{ 'is-alias': item.isAlias === true }"
|
||||||
|
@click="navigate(item.identifier)">
|
||||||
|
<td class="c-list-item__name">
|
||||||
|
<div class="c-list-item__type-icon" :class="(item.cssClass != undefined) ? item.cssClass : 'icon-object-unknown'"></div>
|
||||||
|
{{item.name}}
|
||||||
|
</td>
|
||||||
|
<td class="c-list-item__type">{{ item.type }}</td>
|
||||||
|
<td class="c-list-item__date-created">{{ formatTime(item.createdDate, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z</td>
|
||||||
|
<td class="c-list-item__date-updated">{{ formatTime(item.updatedDate, 'YYYY-MM-DD HH:mm:ss:SSS') }}Z</td>
|
||||||
|
<td class="c-list-item__items">{{ item.items }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
/******************************* LIST VIEW */
|
||||||
|
.c-list-view {
|
||||||
|
overflow-x: auto !important;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
tbody tr {
|
||||||
|
background: $colorListItemBg;
|
||||||
|
transition: $transOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
body.desktop & {
|
||||||
|
tbody tr {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $colorListItemBgHov;
|
||||||
|
transition: $transIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
$p: floor($interiorMargin * 1.5);
|
||||||
|
font-size: 1.1em;
|
||||||
|
padding-top: $p;
|
||||||
|
padding-bottom: $p;
|
||||||
|
|
||||||
|
&:not(.c-list-item__name) {
|
||||||
|
color: $colorItemFgDetails;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-list-item {
|
||||||
|
&__name {
|
||||||
|
@include ellipsize();
|
||||||
|
}
|
||||||
|
|
||||||
|
&__type-icon {
|
||||||
|
color: $colorKey;
|
||||||
|
display: inline-block;
|
||||||
|
width: 1em;
|
||||||
|
margin-right:$interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-alias {
|
||||||
|
// Object is an alias to an original.
|
||||||
|
[class*='__type-icon'] {
|
||||||
|
&:after {
|
||||||
|
color: $colorIconAlias;
|
||||||
|
content: $glyph-icon-link;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
text-shadow: rgba(black, 0.5) 0 1px 2px;
|
||||||
|
top: auto; left: -1px; bottom: 1px; right: auto;
|
||||||
|
transform-origin: bottom left;
|
||||||
|
transform: scale(0.65);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/******************************* LIST ITEM */
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct', 'domainObject', 'Moment'],
|
||||||
|
data() {
|
||||||
|
var items = [],
|
||||||
|
unknownObjectType = {
|
||||||
|
definition: {
|
||||||
|
cssClass: 'icon-object-unknown',
|
||||||
|
name: 'Unknown Type'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
|
||||||
|
if (composition) {
|
||||||
|
|
||||||
|
composition.load().then((array) => {
|
||||||
|
if (Array.isArray(array)) {
|
||||||
|
array.forEach(model => {
|
||||||
|
var type = this.openmct.types.get(model.type) || unknownObjectType;
|
||||||
|
|
||||||
|
items.push({
|
||||||
|
name: model.name,
|
||||||
|
identifier: model.identifier.key,
|
||||||
|
type: type.definition.name,
|
||||||
|
isAlias: false,
|
||||||
|
cssClass: type.definition.cssClass,
|
||||||
|
createdDate: model.persisted,
|
||||||
|
updatedDate: model.modified,
|
||||||
|
items: model.composition ? model.composition.length : 0,
|
||||||
|
isAlias: this.domainObject.identifier.key !== model.location
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
items: items,
|
||||||
|
orderByField: 'name',
|
||||||
|
sortClass: 'asc',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
sortedItems () {
|
||||||
|
if (this.sortClass === 'asc') {
|
||||||
|
return this.items.sort(this.ascending.bind(this));
|
||||||
|
} else if (this.sortClass === 'desc') {
|
||||||
|
return this.items.sort(this.descending.bind(this));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
formatTime () {
|
||||||
|
return function (timestamp, format) {
|
||||||
|
return this.Moment(timestamp).format(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
navigate(identifier) {
|
||||||
|
let currentLocation = this.openmct.router.currentLocation.path,
|
||||||
|
navigateToPath = `${currentLocation}/${identifier}`;
|
||||||
|
|
||||||
|
this.openmct.router.setPath(navigateToPath);
|
||||||
|
},
|
||||||
|
sortTrigger(field, sortOrder) {
|
||||||
|
if (this.orderByField === field) {
|
||||||
|
this.sortClass = (this.sortClass === 'asc') ? 'desc' : 'asc';
|
||||||
|
} else {
|
||||||
|
this.sortClass = sortOrder;
|
||||||
|
}
|
||||||
|
this.orderByField = field;
|
||||||
|
},
|
||||||
|
ascending(first, second) {
|
||||||
|
if (first[this.orderByField] < second[this.orderByField]) {
|
||||||
|
return -1;
|
||||||
|
} else if (first[this.orderByField] > second[this.orderByField]) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
descending(first, second) {
|
||||||
|
if (first[this.orderByField] > second[this.orderByField]) {
|
||||||
|
return -1;
|
||||||
|
} else if (first[this.orderByField] < second[this.orderByField]) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
36
src/plugins/folderView/plugin.js
Normal file
36
src/plugins/folderView/plugin.js
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||||
|
* as represented by the Administrator of the National Aeronautics and Space
|
||||||
|
* Administration. All rights reserved.
|
||||||
|
*
|
||||||
|
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
* Open MCT includes source code licensed under additional open source
|
||||||
|
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||||
|
* this source code distribution or the Licensing information page available
|
||||||
|
* at runtime from the About dialog for additional information.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
define([
|
||||||
|
'./FolderGridView',
|
||||||
|
'./FolderListView'
|
||||||
|
], function (
|
||||||
|
FolderGridView,
|
||||||
|
FolderListView
|
||||||
|
) {
|
||||||
|
return function plugin() {
|
||||||
|
return function install(openmct) {
|
||||||
|
openmct.objectViews.addProvider(new FolderGridView(openmct));
|
||||||
|
openmct.objectViews.addProvider(new FolderListView(openmct));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
@ -34,7 +34,8 @@ define([
|
|||||||
'./plot/plugin',
|
'./plot/plugin',
|
||||||
'./telemetryTable/plugin',
|
'./telemetryTable/plugin',
|
||||||
'./staticRootPlugin/plugin',
|
'./staticRootPlugin/plugin',
|
||||||
'./notebook/plugin'
|
'./notebook/plugin',
|
||||||
|
'./folderView/plugin'
|
||||||
], function (
|
], function (
|
||||||
_,
|
_,
|
||||||
UTCTimeSystem,
|
UTCTimeSystem,
|
||||||
@ -49,7 +50,8 @@ define([
|
|||||||
PlotPlugin,
|
PlotPlugin,
|
||||||
TelemetryTablePlugin,
|
TelemetryTablePlugin,
|
||||||
StaticRootPlugin,
|
StaticRootPlugin,
|
||||||
Notebook
|
Notebook,
|
||||||
|
FolderView
|
||||||
) {
|
) {
|
||||||
var bundleMap = {
|
var bundleMap = {
|
||||||
LocalStorage: 'platform/persistence/local',
|
LocalStorage: 'platform/persistence/local',
|
||||||
@ -159,6 +161,7 @@ define([
|
|||||||
plugins.TelemetryMean = TelemetryMean;
|
plugins.TelemetryMean = TelemetryMean;
|
||||||
plugins.URLIndicator = URLIndicatorPlugin;
|
plugins.URLIndicator = URLIndicatorPlugin;
|
||||||
plugins.Notebook = Notebook;
|
plugins.Notebook = Notebook;
|
||||||
|
plugins.FolderView = FolderView;
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<!-- Headers table -->
|
<!-- Headers table -->
|
||||||
<div class="c-table__headers-w js-table__headers-w">
|
<div class="c-telemetry-table__headers-w js-table__headers-w">
|
||||||
<table class="c-table__headers c-telemetry-table__headers"
|
<table class="c-table__headers c-telemetry-table__headers"
|
||||||
:style="{ 'max-width': totalWidth + 'px'}">
|
:style="{ 'max-width': totalWidth + 'px'}">
|
||||||
<thead>
|
<thead>
|
||||||
@ -68,48 +68,22 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~styles/sass-base";
|
@import "~styles/sass-base";
|
||||||
|
@import "~styles/table";
|
||||||
|
|
||||||
.c-table {
|
.c-telemetry-table {
|
||||||
// Can be used by any type of table, scrolling, LAD, etc.
|
// Table that displays telemetry in a scrolling body area
|
||||||
$min-w: 50px;
|
|
||||||
|
|
||||||
display: flex;
|
|
||||||
flex-flow: column nowrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: absolute;
|
|
||||||
top: 0; right: 0; bottom: 0; left: 0;
|
|
||||||
|
|
||||||
&__control-bar,
|
|
||||||
&__headers-w {
|
|
||||||
// Don't allow top level elements to grow or shrink
|
|
||||||
flex: 0 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************* ELEMENTS */
|
|
||||||
th, td {
|
th, td {
|
||||||
display: block;
|
display: block;
|
||||||
flex: 1 0 auto;
|
flex: 1 0 auto;
|
||||||
font-size: 0.7rem; // TEMP LEGACY TODO: refactor this when __main-container font-size is dealt with
|
|
||||||
white-space: nowrap;
|
|
||||||
min-width: $min-w;
|
|
||||||
padding: $tabularTdPadTB $tabularTdPadLR;
|
|
||||||
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
|
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
|
||||||
}
|
}
|
||||||
|
|
||||||
td {
|
|
||||||
color: $colorTelemFresh;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__control-bar {
|
|
||||||
margin-bottom: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************* WRAPPERS */
|
/******************************* WRAPPERS */
|
||||||
&__headers-w {
|
&__headers-w {
|
||||||
// Wraps __headers table
|
// Wraps __headers table
|
||||||
background: $colorTabHeaderBg;
|
flex: 0 0 auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,65 +109,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&__body {
|
|
||||||
// A table
|
|
||||||
tr {
|
|
||||||
&:not(:first-child) {
|
|
||||||
border-top: 1px solid $colorTabBorder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************* MODIFIERS */
|
|
||||||
&--filterable {
|
|
||||||
// TODO: discuss using the search.vue custom control here
|
|
||||||
|
|
||||||
.l-filter {
|
|
||||||
input[type="text"],
|
|
||||||
input[type="search"] {
|
|
||||||
$p: 20px;
|
|
||||||
transition: padding 200ms ease-in-out;
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-right: $p; // Fend off from icon
|
|
||||||
padding-left: $p; // Fend off from icon
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
&.active {
|
|
||||||
// When user has typed something, hide the icon and collapse left padding
|
|
||||||
&:before {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
input[type="text"],
|
|
||||||
input[type="search"] {
|
|
||||||
padding-left: $interiorMargin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&--sortable {
|
|
||||||
.is-sorting {
|
|
||||||
&:after {
|
|
||||||
color: $colorIconLink;
|
|
||||||
content: $glyph-icon-arrow-tall-up;
|
|
||||||
font-family: symbolsfont;
|
|
||||||
font-size: 8px;
|
|
||||||
display: inline-block;
|
|
||||||
margin-left: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
&.desc:after {
|
|
||||||
content: $glyph-icon-arrow-tall-down;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.is-sortable {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-telemetry-table {
|
|
||||||
// Table that displays telemetry in a scrolling body area
|
|
||||||
|
|
||||||
/******************************* ELEMENTS */
|
/******************************* ELEMENTS */
|
||||||
&__scroll-forcer {
|
&__scroll-forcer {
|
||||||
// Force horz scroll when needed; width set via JS
|
// Force horz scroll when needed; width set via JS
|
||||||
@ -251,10 +166,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-table__control-bar {
|
|
||||||
margin-bottom: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************* LEGACY */
|
/******************************* LEGACY */
|
||||||
.s-status-taking-snapshot,
|
.s-status-taking-snapshot,
|
||||||
.overlay.snapshot {
|
.overlay.snapshot {
|
||||||
|
@ -21,6 +21,7 @@ $colorStatusBarFg: #999;
|
|||||||
$colorStatusBarFgHov: #aaa;
|
$colorStatusBarFgHov: #aaa;
|
||||||
$colorKey: #0099cc;
|
$colorKey: #0099cc;
|
||||||
$colorKeyFilter: brightness(0.9) sepia(1) hue-rotate(145deg) saturate(6);
|
$colorKeyFilter: brightness(0.9) sepia(1) hue-rotate(145deg) saturate(6);
|
||||||
|
$colorKeyFilterHov: brightness(1) sepia(1) hue-rotate(145deg) saturate(7);
|
||||||
$colorKeySelectedBg: $colorKey;
|
$colorKeySelectedBg: $colorKey;
|
||||||
$colorKeyFg: #fff;
|
$colorKeyFg: #fff;
|
||||||
$colorKeyHov: #00c0f6;
|
$colorKeyHov: #00c0f6;
|
||||||
@ -82,7 +83,8 @@ $colorDiagnostic: #a4b442;
|
|||||||
$colorCommand: #3693bd;
|
$colorCommand: #3693bd;
|
||||||
$colorInfo: #2294a2;
|
$colorInfo: #2294a2;
|
||||||
$colorOk: #33cc33;
|
$colorOk: #33cc33;
|
||||||
$colorIconLink: #49dedb;
|
$colorIconAlias: #4af6f3;
|
||||||
|
$colorIconAliasForKeyFilter: #aaa;
|
||||||
$colorPausedBg: #ff9900;
|
$colorPausedBg: #ff9900;
|
||||||
$colorPausedFg: #fff;
|
$colorPausedFg: #fff;
|
||||||
$colorCreateBtn: $colorKey;
|
$colorCreateBtn: $colorKey;
|
||||||
@ -182,7 +184,9 @@ $durLargeViewExpand: 250ms;
|
|||||||
|
|
||||||
// Items
|
// Items
|
||||||
$colorItemBg: #ddd;
|
$colorItemBg: #ddd;
|
||||||
$colorItemBgHov: pullForward($colorItemBg, $hoverRatioPercent * 0.7);
|
$colorItemBgHov: rgba($colorKey, 0.1); //pushBack($colorItemBg, $hoverRatioPercent * 0.4);
|
||||||
|
$colorListItemBg: transparent;
|
||||||
|
$colorListItemBgHov: rgba($colorKey, 0.1);
|
||||||
$colorItemFg: $colorBodyFg;
|
$colorItemFg: $colorBodyFg;
|
||||||
$colorItemFgDetails: pushBack($colorItemFg, 15%);
|
$colorItemFgDetails: pushBack($colorItemFg, 15%);
|
||||||
$colorItemIc: $colorKey;
|
$colorItemIc: $colorKey;
|
||||||
@ -292,8 +296,10 @@ $colorLoadingFg: $colorAlt1;
|
|||||||
$colorLoadingBg: rgba($colorLoadingFg, 0.1);
|
$colorLoadingBg: rgba($colorLoadingFg, 0.1);
|
||||||
|
|
||||||
// Transitions
|
// Transitions
|
||||||
$transIn: all 50ms ease-in;
|
$transIn: all 50ms ease-in-out;
|
||||||
$transOut: all 250ms ease-out;
|
$transOut: all 250ms ease-in-out;
|
||||||
|
$transInBounce: all 200ms cubic-bezier(.47,.01,.25,1.5);
|
||||||
|
$transInBounceBig: all 300ms cubic-bezier(.2,1.6,.6,3);
|
||||||
|
|
||||||
// Discrete items, like Notebook entries, Widget rules
|
// Discrete items, like Notebook entries, Widget rules
|
||||||
@mixin discreteItem() {
|
@mixin discreteItem() {
|
||||||
|
69
src/styles-new/_table.scss
Normal file
69
src/styles-new/_table.scss
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/******************************************************** TABLE */
|
||||||
|
.c-table {
|
||||||
|
// Can be used by any type of table, scrolling, LAD, etc.
|
||||||
|
$min-w: 50px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
position: absolute;
|
||||||
|
top: 0; right: 0; bottom: 0; left: 0;
|
||||||
|
|
||||||
|
&__control-bar,
|
||||||
|
&__headers-w {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************* ELEMENTS */
|
||||||
|
th, td {
|
||||||
|
white-space: nowrap;
|
||||||
|
min-width: $min-w;
|
||||||
|
padding: $tabularTdPadTB $tabularTdPadLR;
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
color: $colorTelemFresh;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__control-bar {
|
||||||
|
margin-bottom: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*="__header"] {
|
||||||
|
background: $colorTabHeaderBg;
|
||||||
|
|
||||||
|
th {
|
||||||
|
&:not(:first-child) {
|
||||||
|
border-left: 1px solid $colorTabHeaderBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__body {
|
||||||
|
tr {
|
||||||
|
&:not(:first-child) {
|
||||||
|
border-top: 1px solid $colorTabBorder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--sortable {
|
||||||
|
.is-sorting {
|
||||||
|
&:after {
|
||||||
|
color: $colorIconAlias;
|
||||||
|
content: $glyph-icon-arrow-tall-up;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 8px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
&.desc:after {
|
||||||
|
content: $glyph-icon-arrow-tall-down;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.is-sortable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -13,7 +13,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~styles/sass-base";;
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
/******************************* SEARCH */
|
/******************************* SEARCH */
|
||||||
.c-search {
|
.c-search {
|
||||||
|
@ -113,8 +113,6 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~styles/sass-base";
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
/******************************* START */
|
|
||||||
|
|
||||||
.l-browse-bar {
|
.l-browse-bar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
@ -3,8 +3,14 @@
|
|||||||
<div class="l-shell__head">
|
<div class="l-shell__head">
|
||||||
<CreateButton class="l-shell__create-button"></CreateButton>
|
<CreateButton class="l-shell__create-button"></CreateButton>
|
||||||
<div class="l-shell__controls">
|
<div class="l-shell__controls">
|
||||||
<a class="c-icon-button icon-new-window" title="Open in a new browser tab"></a>
|
<a class="c-icon-button icon-new-window" title="Open in a new browser tab"
|
||||||
<a class="c-icon-button icon-fullscreen-collapse" title="Enable full screen mode"></a>
|
@click="openInNewTab"
|
||||||
|
target="_blank">
|
||||||
|
</a>
|
||||||
|
<a v-bind:class="['c-icon-button', fullScreen ? 'icon-fullscreen-expand' : 'icon-fullscreen-collapse']"
|
||||||
|
v-bind:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||||
|
@click="fullScreenToggle">
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="l-shell__app-logo">[ App Logo ]</div>
|
<div class="l-shell__app-logo">[ App Logo ]</div>
|
||||||
</div>
|
</div>
|
||||||
@ -129,6 +135,10 @@
|
|||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.mobile & .l-shell__main-view-browse-bar {
|
||||||
|
margin-left: $mobileMenuIconD - $interiorMarginLg; // Make room for the hamburger!
|
||||||
|
}
|
||||||
|
|
||||||
&__head {
|
&__head {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@ -203,6 +213,34 @@
|
|||||||
import pane from '../controls/pane.vue';
|
import pane from '../controls/pane.vue';
|
||||||
import BrowseBar from './BrowseBar.vue';
|
import BrowseBar from './BrowseBar.vue';
|
||||||
|
|
||||||
|
var enterFullScreen = () => {
|
||||||
|
var docElm = document.documentElement;
|
||||||
|
|
||||||
|
if (docElm.requestFullscreen) {
|
||||||
|
docElm.requestFullscreen();
|
||||||
|
} else if (docElm.mozRequestFullScreen) { /* Firefox */
|
||||||
|
docElm.mozRequestFullScreen();
|
||||||
|
} else if (docElm.webkitRequestFullscreen) { /* Chrome, Safari and Opera */
|
||||||
|
docElm.webkitRequestFullscreen();
|
||||||
|
} else if (docElm.msRequestFullscreen) { /* IE/Edge */
|
||||||
|
docElm.msRequestFullscreen();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var exitFullScreen = () => {
|
||||||
|
if (document.exitFullscreen) {
|
||||||
|
document.exitFullscreen();
|
||||||
|
}
|
||||||
|
else if (document.mozCancelFullScreen) {
|
||||||
|
document.mozCancelFullScreen();
|
||||||
|
}
|
||||||
|
else if (document.webkitCancelFullScreen) {
|
||||||
|
document.webkitCancelFullScreen();
|
||||||
|
}
|
||||||
|
else if (document.msExitFullscreen) {
|
||||||
|
document.msExitFullscreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Inspector,
|
Inspector,
|
||||||
@ -216,6 +254,26 @@
|
|||||||
multipane,
|
multipane,
|
||||||
pane,
|
pane,
|
||||||
BrowseBar
|
BrowseBar
|
||||||
|
},
|
||||||
|
data: () => {
|
||||||
|
return {
|
||||||
|
fullScreen: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fullScreenToggle () {
|
||||||
|
|
||||||
|
if (this.fullScreen) {
|
||||||
|
this.fullScreen = false;
|
||||||
|
exitFullScreen();
|
||||||
|
} else {
|
||||||
|
this.fullScreen = true;
|
||||||
|
enterFullScreen();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openInNewTab (event) {
|
||||||
|
event.target.href = window.location.href;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user