Compare commits
	
		
			8 Commits
		
	
	
		
			vista-4.1-
			...
			table-perf
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					a8ebf3d00c | ||
| 
						 | 
					bc5e300ba9 | ||
| 
						 | 
					57efef3160 | ||
| 
						 | 
					dfc5a9f040 | ||
| 
						 | 
					57443d227d | ||
| 
						 | 
					d36441db73 | ||
| 
						 | 
					327782835e | ||
| 
						 | 
					994f6be535 | 
@@ -54,6 +54,9 @@
 | 
			
		||||
        openmct.install(openmct.plugins.AutoflowView({
 | 
			
		||||
            type: "telemetry.panel"
 | 
			
		||||
        }));
 | 
			
		||||
        openmct.install(openmct.plugins.DisplayLayout({
 | 
			
		||||
            showAsView: ['summary-widget', 'example.imagery']
 | 
			
		||||
        }));
 | 
			
		||||
        openmct.install(openmct.plugins.Conductor({
 | 
			
		||||
            menuOptions: [
 | 
			
		||||
                {
 | 
			
		||||
 
 | 
			
		||||
@@ -162,9 +162,6 @@ function (
 | 
			
		||||
        function saveAfterClone(clonedObject) {
 | 
			
		||||
            return this.openmct.editor.save().then(() => {
 | 
			
		||||
                // Force mutation for search indexing
 | 
			
		||||
                clonedObject.useCapability('mutation', (model) => {
 | 
			
		||||
                    return model;
 | 
			
		||||
                });
 | 
			
		||||
                return clonedObject;
 | 
			
		||||
            })
 | 
			
		||||
        }
 | 
			
		||||
@@ -173,6 +170,14 @@ function (
 | 
			
		||||
            return fetchObject(clonedObject.getId())
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function indexForSearch(savedObject) {
 | 
			
		||||
            savedObject.useCapability('mutation', (model) => {
 | 
			
		||||
                return model;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            return savedObject;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function onSuccess(object) {
 | 
			
		||||
            self.notificationService.info("Save Succeeded");
 | 
			
		||||
            return object;
 | 
			
		||||
@@ -194,6 +199,7 @@ function (
 | 
			
		||||
            .then(undirtyOriginals)
 | 
			
		||||
            .then(saveAfterClone)
 | 
			
		||||
            .then(finishEditing)
 | 
			
		||||
            .then(indexForSearch)
 | 
			
		||||
            .then(hideBlockingDialog)
 | 
			
		||||
            .then(onSuccess)
 | 
			
		||||
            .catch(onFailure);
 | 
			
		||||
 
 | 
			
		||||
@@ -37,75 +37,17 @@ define(
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Handle persistence failures by providing the user with a
 | 
			
		||||
         * dialog summarizing these failures, and giving the option
 | 
			
		||||
         * to overwrite/cancel as appropriate.
 | 
			
		||||
         * Discard failures
 | 
			
		||||
         * @param {Array} failures persistence failures, as prepared
 | 
			
		||||
         *        by PersistenceQueueHandler
 | 
			
		||||
         * @memberof platform/persistence/queue.PersistenceFailureHandler#
 | 
			
		||||
         */
 | 
			
		||||
        PersistenceFailureHandler.prototype.handle = function handleFailures(failures) {
 | 
			
		||||
            // Prepare dialog for display
 | 
			
		||||
 | 
			
		||||
            var dialogModel = new PersistenceFailureDialog(failures),
 | 
			
		||||
                revisionErrors = dialogModel.model.revised,
 | 
			
		||||
                $q = this.$q;
 | 
			
		||||
 | 
			
		||||
            // Refresh revision information for the domain object associated
 | 
			
		||||
            // with this persistence failure
 | 
			
		||||
            function refresh(failure) {
 | 
			
		||||
                // Refresh the domain object to the latest from persistence
 | 
			
		||||
                return failure.persistence.refresh();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Issue a new persist call for the domain object associated with
 | 
			
		||||
            // this failure.
 | 
			
		||||
            function persist(failure) {
 | 
			
		||||
                // Note that we reissue the persist request here, but don't
 | 
			
		||||
                // return it, to avoid a circular wait. We trust that the
 | 
			
		||||
                // PersistenceQueue will behave correctly on the next round
 | 
			
		||||
                // of flushing.
 | 
			
		||||
                failure.requeue();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Retry persistence (overwrite) for this set of failed attempts
 | 
			
		||||
            function retry(failuresToRetry) {
 | 
			
		||||
                var models = {};
 | 
			
		||||
 | 
			
		||||
                // Cache a copy of the model
 | 
			
		||||
                function cacheModel(failure) {
 | 
			
		||||
                    // Clone...
 | 
			
		||||
                    models[failure.id] = JSON.parse(JSON.stringify(
 | 
			
		||||
                        failure.domainObject.getModel()
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Mutate a domain object to restore its model
 | 
			
		||||
                function remutate(failure) {
 | 
			
		||||
                    var model = models[failure.id];
 | 
			
		||||
                    return failure.domainObject.useCapability(
 | 
			
		||||
                        "mutation",
 | 
			
		||||
                        function () {
 | 
			
		||||
                            return model;
 | 
			
		||||
                        },
 | 
			
		||||
                        model.modified
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Cache the object models we might want to save
 | 
			
		||||
                failuresToRetry.forEach(cacheModel);
 | 
			
		||||
 | 
			
		||||
                // Strategy here:
 | 
			
		||||
                // * Cache all of the models we might want to save (above)
 | 
			
		||||
                // * Refresh all domain objects (so they are latest versions)
 | 
			
		||||
                // * Re-insert the cached domain object models
 | 
			
		||||
                // * Invoke persistence again
 | 
			
		||||
                return $q.all(failuresToRetry.map(refresh)).then(function () {
 | 
			
		||||
                    return $q.all(failuresToRetry.map(remutate));
 | 
			
		||||
                }).then(function () {
 | 
			
		||||
                    return $q.all(failuresToRetry.map(persist));
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Discard changes for a failed refresh
 | 
			
		||||
            function discard(failure) {
 | 
			
		||||
                var persistence =
 | 
			
		||||
@@ -118,19 +60,7 @@ define(
 | 
			
		||||
                return $q.all(failuresToDiscard.map(discard));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Handle user input (did they choose to overwrite?)
 | 
			
		||||
            function handleChoice(key) {
 | 
			
		||||
                // If so, try again
 | 
			
		||||
                if (key === PersistenceFailureConstants.OVERWRITE_KEY) {
 | 
			
		||||
                    return retry(revisionErrors);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return discardAll(revisionErrors);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Prompt for user input, the overwrite if they said so.
 | 
			
		||||
            return this.dialogService.getUserChoice(dialogModel)
 | 
			
		||||
                .then(handleChoice, handleChoice);
 | 
			
		||||
            return discardAll(revisionErrors);
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        return PersistenceFailureHandler;
 | 
			
		||||
 
 | 
			
		||||
@@ -74,43 +74,14 @@ define(
 | 
			
		||||
                handler = new PersistenceFailureHandler(mockQ, mockDialogService);
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("shows a dialog to handle failures", function () {
 | 
			
		||||
            it("discards on handle", function () {
 | 
			
		||||
                handler.handle(mockFailures);
 | 
			
		||||
                expect(mockDialogService.getUserChoice).toHaveBeenCalled();
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("overwrites on request", function () {
 | 
			
		||||
                mockQ.all.and.returnValue(asPromise([]));
 | 
			
		||||
                handler.handle(mockFailures);
 | 
			
		||||
                // User chooses overwrite
 | 
			
		||||
                mockPromise.then.calls.mostRecent().args[0](Constants.OVERWRITE_KEY);
 | 
			
		||||
                // Should refresh, remutate, and requeue all objects
 | 
			
		||||
                mockFailures.forEach(function (mockFailure, i) {
 | 
			
		||||
                    expect(mockFailure.persistence.refresh).toHaveBeenCalled();
 | 
			
		||||
                    expect(mockFailure.requeue).toHaveBeenCalled();
 | 
			
		||||
                    expect(mockFailure.domainObject.useCapability).toHaveBeenCalledWith(
 | 
			
		||||
                        'mutation',
 | 
			
		||||
                        jasmine.any(Function),
 | 
			
		||||
                        i // timestamp
 | 
			
		||||
                    );
 | 
			
		||||
                    expect(mockFailure.domainObject.useCapability.calls.mostRecent().args[1]())
 | 
			
		||||
                        .toEqual({ id: mockFailure.id, modified: i });
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            it("discards on request", function () {
 | 
			
		||||
                mockQ.all.and.returnValue(asPromise([]));
 | 
			
		||||
                handler.handle(mockFailures);
 | 
			
		||||
                // User chooses overwrite
 | 
			
		||||
                mockPromise.then.calls.mostRecent().args[0](false);
 | 
			
		||||
                // Should refresh, but not remutate, and requeue all objects
 | 
			
		||||
                mockFailures.forEach(function (mockFailure) {
 | 
			
		||||
                    expect(mockFailure.persistence.refresh).toHaveBeenCalled();
 | 
			
		||||
                    expect(mockFailure.requeue).not.toHaveBeenCalled();
 | 
			
		||||
                    expect(mockFailure.domainObject.useCapability).not.toHaveBeenCalled();
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 
 | 
			
		||||
@@ -248,7 +248,6 @@ define([
 | 
			
		||||
        this.legacyRegistry = defaultRegistry;
 | 
			
		||||
        this.install(this.plugins.Plot());
 | 
			
		||||
        this.install(this.plugins.TelemetryTable());
 | 
			
		||||
        this.install(this.plugins.DisplayLayout());
 | 
			
		||||
        this.install(PreviewPlugin.default());
 | 
			
		||||
        this.install(LegacyIndicatorsPlugin());
 | 
			
		||||
        this.install(LicensesPlugin.default());
 | 
			
		||||
@@ -257,7 +256,6 @@ define([
 | 
			
		||||
        if (typeof BUILD_CONSTANTS !== 'undefined') {
 | 
			
		||||
            this.install(buildInfoPlugin(BUILD_CONSTANTS));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MCT.prototype = Object.create(EventEmitter.prototype);
 | 
			
		||||
@@ -328,6 +326,12 @@ define([
 | 
			
		||||
     *        MCT; if undefined, MCT will be run in the body of the document
 | 
			
		||||
     */
 | 
			
		||||
    MCT.prototype.start = function (domElement) {
 | 
			
		||||
        if (!this.plugins.DisplayLayout._installed) {
 | 
			
		||||
            this.install(this.plugins.DisplayLayout({
 | 
			
		||||
                showAsView: ['summary-widget']
 | 
			
		||||
            }));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!domElement) {
 | 
			
		||||
            domElement = document.body;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -137,8 +137,7 @@ define([
 | 
			
		||||
        function callbackWrapper(series) {
 | 
			
		||||
            callback(createDatum(domainObject, metadata, series, series.getPointCount() - 1));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return capability.subscribe(callbackWrapper, request);
 | 
			
		||||
        return capability.subscribe(callbackWrapper, request) || function () {};
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    LegacyTelemetryProvider.prototype.supportsLimits = function (domainObject) {
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,7 @@
 | 
			
		||||
 | 
			
		||||
    .c-message {
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: flex-start;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
 | 
			
		||||
        > * + * {
 | 
			
		||||
            margin-left: $interiorMarginLg;
 | 
			
		||||
@@ -66,6 +66,17 @@
 | 
			
		||||
            font-size: 1.2em; // TEMP
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &--simple {
 | 
			
		||||
            // Icon and text elements only
 | 
			
		||||
            &:before {
 | 
			
		||||
                font-size: 30px !important;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            [class*='__text'] {
 | 
			
		||||
                font-size: 1.25em;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /************************** LEGACY */
 | 
			
		||||
        &.message-severity-info:before {
 | 
			
		||||
            @include legacyMessage();
 | 
			
		||||
 
 | 
			
		||||
@@ -152,7 +152,7 @@
 | 
			
		||||
                return this.internalDomainObject.configuration.items;
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        inject: ['openmct'],
 | 
			
		||||
        inject: ['openmct', 'options'],
 | 
			
		||||
        props: ['domainObject'],
 | 
			
		||||
        components: ITEM_TYPE_VIEW_MAP,
 | 
			
		||||
        methods: {
 | 
			
		||||
@@ -283,9 +283,8 @@
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            isTelemetry(domainObject) {
 | 
			
		||||
                if (this.openmct.telemetry.isTelemetryObject(domainObject)
 | 
			
		||||
                    && domainObject.type !== 'summary-widget'
 | 
			
		||||
                    && domainObject.type !== 'example.imagery') {
 | 
			
		||||
                if (this.openmct.telemetry.isTelemetryObject(domainObject) && 
 | 
			
		||||
                    !this.options.showAsView.includes(domainObject.type)) {
 | 
			
		||||
                    return true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    return false;
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,7 @@ import Vue from 'vue'
 | 
			
		||||
import objectUtils from '../../api/objects/object-utils.js'
 | 
			
		||||
import DisplayLayoutType from './DisplayLayoutType.js'
 | 
			
		||||
import DisplayLayoutToolbar from './DisplayLayoutToolbar.js'
 | 
			
		||||
 | 
			
		||||
export default function () {
 | 
			
		||||
export default function DisplayLayoutPlugin(options) {
 | 
			
		||||
    return function (openmct) {
 | 
			
		||||
        openmct.objectViews.addProvider({
 | 
			
		||||
            key: 'layout.view',
 | 
			
		||||
@@ -47,7 +46,8 @@ export default function () {
 | 
			
		||||
                            template: '<layout ref="displayLayout" :domain-object="domainObject"></layout>',
 | 
			
		||||
                            provide: {
 | 
			
		||||
                                openmct,
 | 
			
		||||
                                objectUtils
 | 
			
		||||
                                objectUtils,
 | 
			
		||||
                                options
 | 
			
		||||
                            },
 | 
			
		||||
                            el: container,
 | 
			
		||||
                            data () {
 | 
			
		||||
@@ -83,5 +83,6 @@ export default function () {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        DisplayLayoutPlugin._installed = true;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -76,7 +76,6 @@ define([
 | 
			
		||||
    PlotOptionsController.prototype.addSeries = function (series, index) {
 | 
			
		||||
        this.$scope.plotSeries[index] = series;
 | 
			
		||||
        series.locateOldObject(this.$scope.domainObject);
 | 
			
		||||
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    PlotOptionsController.prototype.resetAllSeries = function (series, index) {
 | 
			
		||||
 
 | 
			
		||||
@@ -219,6 +219,7 @@ define([
 | 
			
		||||
 | 
			
		||||
    PlotController.prototype.stopLoading = function () {
 | 
			
		||||
        this.$scope.pending -= 1;
 | 
			
		||||
        this.$scope.$digest();
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,9 @@
 | 
			
		||||
        <div id="widgetIcon" class="c-sw__icon js-sw__icon"></div>
 | 
			
		||||
        <div id="widgetLabel" class="label widget-label c-sw__label js-sw__label">Default Static Name</div>
 | 
			
		||||
    </a>
 | 
			
		||||
    <div class="c-summary-widget__message holder flex-elem t-message-inline c-message message-severity-alert t-message-widget-no-data">
 | 
			
		||||
        <div class="w-message-contents l-message-body-only">
 | 
			
		||||
            <div class="message-body">
 | 
			
		||||
                You must add at least one telemetry object to edit this widget.
 | 
			
		||||
            </div>
 | 
			
		||||
    <div class="js-summary-widget__message c-summary-widget__message c-message c-message--simple message-severity-alert">
 | 
			
		||||
        <div class="c-summary-widget__text">
 | 
			
		||||
            You must add at least one telemetry object to edit this widget.
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="c-sw-edit__ui holder l-flex-accordion flex-elem grows widget-edit-holder expanded-widget-test-data expanded-widget-rules">
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,8 @@
 | 
			
		||||
            v-for="(tab, index) in tabsList"
 | 
			
		||||
            :key="index"
 | 
			
		||||
            :class="{'invisible': !isCurrent(tab)}">
 | 
			
		||||
            <div class="c-tabs-view__object-name l-browse-bar__object-name--w"
 | 
			
		||||
            <div v-if="currentTab"
 | 
			
		||||
                 class="c-tabs-view__object-name l-browse-bar__object-name--w"
 | 
			
		||||
                 :class="currentTab.type.definition.cssClass">
 | 
			
		||||
                <div class="l-browse-bar__object-name">
 | 
			
		||||
                    {{currentTab.domainObject.name}}
 | 
			
		||||
@@ -81,6 +82,7 @@
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &__empty-message {
 | 
			
		||||
            background: rgba($colorBodyFg, 0.1);
 | 
			
		||||
            color: rgba($colorBodyFg, 0.7);
 | 
			
		||||
            font-style: italic;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
@@ -145,6 +147,13 @@ export default {
 | 
			
		||||
                this.showTab(this.tabsList[this.tabsList.length - 1]);
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        onReorder(reorderPlan) {
 | 
			
		||||
            let oldTabs = this.tabsList.slice();
 | 
			
		||||
 | 
			
		||||
            reorderPlan.forEach(reorderEvent => {
 | 
			
		||||
                this.$set(this.tabsList, reorderEvent.newIndex, oldTabs[reorderEvent.oldIndex]);
 | 
			
		||||
            });
 | 
			
		||||
        },
 | 
			
		||||
        onDrop(e) {
 | 
			
		||||
            this.setCurrentTab = true;
 | 
			
		||||
        },
 | 
			
		||||
@@ -171,6 +180,7 @@ export default {
 | 
			
		||||
        if (this.composition) {
 | 
			
		||||
            this.composition.on('add', this.addItem);
 | 
			
		||||
            this.composition.on('remove', this.removeItem);
 | 
			
		||||
            this.composition.on('reorder', this.onReorder);
 | 
			
		||||
            this.composition.load();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -187,6 +197,7 @@ export default {
 | 
			
		||||
    destroyed() {
 | 
			
		||||
        this.composition.off('add', this.addItem);
 | 
			
		||||
        this.composition.off('remove', this.removeItem);
 | 
			
		||||
        this.composition.off('reorder', this.onReorder);
 | 
			
		||||
 | 
			
		||||
        document.removeEventListener('dragstart', this.dragstart);
 | 
			
		||||
        document.removeEventListener('dragend', this.dragend);
 | 
			
		||||
 
 | 
			
		||||
@@ -32,12 +32,20 @@ define([
 | 
			
		||||
    Vue
 | 
			
		||||
) {
 | 
			
		||||
    function TelemetryTableViewProvider(openmct) {
 | 
			
		||||
        function hasTelemetry(domainObject) {
 | 
			
		||||
            if (!domainObject.hasOwnProperty('telemetry')) {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            let metadata = openmct.telemetry.getMetadata(domainObject);
 | 
			
		||||
            return metadata.values().length > 0;
 | 
			
		||||
        }
 | 
			
		||||
        return {
 | 
			
		||||
            key: 'table',
 | 
			
		||||
            name: 'Telemetry Table',
 | 
			
		||||
            cssClass: 'icon-tabular-realtime',
 | 
			
		||||
            canView(domainObject) {
 | 
			
		||||
                return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
 | 
			
		||||
                return domainObject.type === 'table' ||
 | 
			
		||||
                    hasTelemetry(domainObject)
 | 
			
		||||
            },
 | 
			
		||||
            canEdit(domainObject) {
 | 
			
		||||
                return domainObject.type === 'table';
 | 
			
		||||
 
 | 
			
		||||
@@ -432,9 +432,9 @@ export default {
 | 
			
		||||
        shouldSnapToBottom() {
 | 
			
		||||
            return this.scrollable.scrollTop >= (this.scrollable.scrollHeight - this.scrollable.offsetHeight - AUTO_SCROLL_TRIGGER_HEIGHT);
 | 
			
		||||
        },
 | 
			
		||||
        scrollToBottom() {
 | 
			
		||||
        scrollToBottom: _.throttle(function() {
 | 
			
		||||
            this.scrollable.scrollTop = this.scrollable.scrollHeight;
 | 
			
		||||
        },
 | 
			
		||||
        }, 100),
 | 
			
		||||
        synchronizeScrollX() {
 | 
			
		||||
            this.headersHolderEl.scrollLeft = this.scrollable.scrollLeft;
 | 
			
		||||
        },
 | 
			
		||||
 
 | 
			
		||||
@@ -126,7 +126,6 @@
 | 
			
		||||
            grid-template-rows: 1fr;
 | 
			
		||||
            grid-template-columns: 20px auto 1fr auto;
 | 
			
		||||
            grid-template-areas: "tc-mode-icon tc-start tc-ticks tc-end";
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &__mode-icon {
 | 
			
		||||
 
 | 
			
		||||
@@ -80,7 +80,7 @@ $formLabelW: 30%;
 | 
			
		||||
$waitSpinnerD: 32px;
 | 
			
		||||
$waitSpinnerTreeD: 20px;
 | 
			
		||||
$waitSpinnerBorderW: 5px;
 | 
			
		||||
$waitSpinnerTreeBorderW: 4px;
 | 
			
		||||
$waitSpinnerTreeBorderW: 3px;
 | 
			
		||||
/*************** Messages */
 | 
			
		||||
$messageIconD: 80px;
 | 
			
		||||
$messageListIconD: 32px;
 | 
			
		||||
 
 | 
			
		||||
@@ -143,7 +143,7 @@
 | 
			
		||||
    @include nice-input();
 | 
			
		||||
    padding: $interiorMargin;
 | 
			
		||||
    position: relative;
 | 
			
		||||
    min-height: 150px;
 | 
			
		||||
    min-height: 0; // Chrome 73 overflow bug fix
 | 
			
		||||
    height: 100%;
 | 
			
		||||
    >.wrapper {
 | 
			
		||||
        $p: $interiorMargin;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,8 +19,7 @@
 | 
			
		||||
 * this source code distribution or the Licensing information page available
 | 
			
		||||
 * at runtime from the About dialog for additional information.
 | 
			
		||||
 *****************************************************************************/
 | 
			
		||||
 | 
			
		||||
/******************************* RESETS */
 | 
			
		||||
/******************************************************** RESETS */
 | 
			
		||||
*,
 | 
			
		||||
:before,
 | 
			
		||||
:after {
 | 
			
		||||
@@ -31,7 +30,7 @@ div {
 | 
			
		||||
    position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************* UTILITIES */
 | 
			
		||||
/******************************************************** UTILITIES */
 | 
			
		||||
.u-contents {
 | 
			
		||||
    display: contents;
 | 
			
		||||
}
 | 
			
		||||
@@ -45,7 +44,7 @@ div {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************* BROWSER ELEMENTS */
 | 
			
		||||
/******************************************************** BROWSER ELEMENTS */
 | 
			
		||||
body.desktop {
 | 
			
		||||
    ::-webkit-scrollbar {
 | 
			
		||||
        box-sizing: border-box;
 | 
			
		||||
@@ -75,7 +74,7 @@ body.desktop {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/************************** HTML ENTITIES */
 | 
			
		||||
/******************************************************** HTML ENTITIES */
 | 
			
		||||
a {
 | 
			
		||||
    color: $colorA;
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
@@ -167,7 +166,6 @@ body.desktop .has-local-controls {
 | 
			
		||||
 | 
			
		||||
/******************************************************** SELECTION AND EDITING */
 | 
			
		||||
// Provides supporting styles for Display Layouts and augmented legacy Fixed Position view
 | 
			
		||||
 | 
			
		||||
.c-grid,
 | 
			
		||||
.c-grid__x,
 | 
			
		||||
.c-grid__y {
 | 
			
		||||
@@ -204,169 +202,88 @@ body.desktop .has-local-controls {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/************************** LEGACY */
 | 
			
		||||
 | 
			
		||||
mct-container {
 | 
			
		||||
/******************************************************** STATES */
 | 
			
		||||
@mixin  spinner($b: 5px, $c: $colorKey) {
 | 
			
		||||
    animation-name: rotation-centered;
 | 
			
		||||
    animation-duration: 0.5s;
 | 
			
		||||
    animation-iteration-count: infinite;
 | 
			
		||||
    animation-timing-function: linear;
 | 
			
		||||
    border-radius: 100%;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    border-color: rgba($c, 0.25);
 | 
			
		||||
    border-top-color: rgba($c, 1.0);
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: $b;
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.abs {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    height: auto;
 | 
			
		||||
    width: auto;
 | 
			
		||||
    left: 50%; top: 50%;
 | 
			
		||||
    transform-origin: center;
 | 
			
		||||
    transform: translate(-50%, -50%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code {
 | 
			
		||||
    font-family: "Lucida Console", monospace;
 | 
			
		||||
    font-size: 0.7em;
 | 
			
		||||
    line-height: 150%;
 | 
			
		||||
    white-space: pre;
 | 
			
		||||
.wait-spinner {
 | 
			
		||||
    @include spinner($waitSpinnerBorderW, $colorKey);
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    z-index: 2;
 | 
			
		||||
    &.inline {
 | 
			
		||||
        display: inline-block !important;
 | 
			
		||||
        margin-right: $interiorMargin;
 | 
			
		||||
        position: relative !important;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.codehilite {
 | 
			
		||||
    @extend .code;
 | 
			
		||||
    background-color: rgba($colorBodyFg, 0.1);
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
.loading {
 | 
			
		||||
    // Can be applied to any block element with height and width
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    &:before,
 | 
			
		||||
    &:after {
 | 
			
		||||
        content: '';
 | 
			
		||||
    }
 | 
			
		||||
    &:before {
 | 
			
		||||
        @include spinner($waitSpinnerBorderW, $colorLoadingFg);
 | 
			
		||||
        height: $waitSpinnerD; width: $waitSpinnerD;
 | 
			
		||||
        z-index: 10;
 | 
			
		||||
    }
 | 
			
		||||
    &:after {
 | 
			
		||||
        @include abs();
 | 
			
		||||
        background: $colorLoadingBg;
 | 
			
		||||
        display: block;
 | 
			
		||||
        z-index: 9;
 | 
			
		||||
    }
 | 
			
		||||
    &.c-tree__item {
 | 
			
		||||
        $d: $waitSpinnerTreeD;
 | 
			
		||||
        $spinnerL: 19px + $d/2;
 | 
			
		||||
 | 
			
		||||
        display: flex;
 | 
			
		||||
        align-items: center;
 | 
			
		||||
        padding-left: $spinnerL + $d/2 + $interiorMargin;
 | 
			
		||||
        background: $colorLoadingBg;
 | 
			
		||||
        min-height: 5px + $d;
 | 
			
		||||
 | 
			
		||||
        .c-tree__item__label {
 | 
			
		||||
            font-style: italic;
 | 
			
		||||
            opacity: 0.6;
 | 
			
		||||
        }
 | 
			
		||||
        &:before {
 | 
			
		||||
            height: $d;
 | 
			
		||||
            width: $d;
 | 
			
		||||
            border-width: 4px;
 | 
			
		||||
            left: $spinnerL;
 | 
			
		||||
        }
 | 
			
		||||
        &:after {
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.c-loading--overlay {
 | 
			
		||||
        @include abs();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
*[disabled],
 | 
			
		||||
.disabled,
 | 
			
		||||
a.disabled {
 | 
			
		||||
.disabled {
 | 
			
		||||
    opacity: $controlDisabledOpacity;
 | 
			
		||||
    pointer-events: none !important;
 | 
			
		||||
    cursor: default !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.s-status-missing {
 | 
			
		||||
    // Labels. Expects .s-status-missing to be applied to mct-representation that contains
 | 
			
		||||
    .t-object-label .t-item-icon:before {
 | 
			
		||||
        content: $glyph-icon-object-unknown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Item, grid item. Expects .s-status-missing to be applied to mct-representation that contains .item.grid-item
 | 
			
		||||
    .item .t-item-icon-glyph:before {
 | 
			
		||||
        content: $glyph-icon-object-unknown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Object header. Expects .s-status-missing to be applied to mct-representation.object-header
 | 
			
		||||
    &.object-header {
 | 
			
		||||
        .type-icon:before {
 | 
			
		||||
            content: $glyph-icon-object-unknown;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Tree item. Expects .s-status-missing to be applied to .tree-item,
 | 
			
		||||
    // and mct-representation.search-item
 | 
			
		||||
    &.tree-item,
 | 
			
		||||
    &.search-item {
 | 
			
		||||
        > .rep-object-label .t-item-icon:before {
 | 
			
		||||
            content: $glyph-icon-object-unknown;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-right {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.centered {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-selection {
 | 
			
		||||
    // aka selection = "None". Used in palettes and their menu buttons.
 | 
			
		||||
    $c: red;
 | 
			
		||||
    $s: 48%;
 | 
			
		||||
    $e: 52%;
 | 
			
		||||
    background-image: linear-gradient(-45deg,
 | 
			
		||||
            transparent $s - 5%,
 | 
			
		||||
            $c $s,
 | 
			
		||||
            $c $e,
 | 
			
		||||
            transparent $e + 5%
 | 
			
		||||
    );
 | 
			
		||||
    box-shadow:inset rgba(black, 0.3) 0 0 0 1px;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    background-size: contain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.scrolling,
 | 
			
		||||
.scroll {
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.vscroll {
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    &.scroll-pad {
 | 
			
		||||
        padding-right: $interiorMargin;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.vscroll--persist {
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
    overflow-y: scroll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.slidable {
 | 
			
		||||
    cursor: move; // Fallback
 | 
			
		||||
    cursor: grab;
 | 
			
		||||
    cursor: -moz-grab;
 | 
			
		||||
    cursor: -webkit-grab;
 | 
			
		||||
    &.horz {
 | 
			
		||||
        cursor: col-resize;
 | 
			
		||||
    }
 | 
			
		||||
    &.vert {
 | 
			
		||||
        cursor: row-resize;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-margin {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ds {
 | 
			
		||||
    box-shadow: rgba(#000, 0.7) 0 4px 10px 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.capitalize {
 | 
			
		||||
    text-transform: capitalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hide,
 | 
			
		||||
.hidden,
 | 
			
		||||
.t-main-view .hide-in-t-main-view {
 | 
			
		||||
    display: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hide-nice {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.invisible {
 | 
			
		||||
    display: block;
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
    height: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    margin: 0 !important;
 | 
			
		||||
    transform: scale(0);
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sep {
 | 
			
		||||
    color: rgba(#fff, 0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.comma-list span {
 | 
			
		||||
    &:not(:first-child) {
 | 
			
		||||
        &:before {
 | 
			
		||||
            content: ', ';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -461,7 +461,7 @@ body.mobile.phone {
 | 
			
		||||
    width: $ruleLabelW;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.t-message-widget-no-data {
 | 
			
		||||
.js-summary-widget__message {
 | 
			
		||||
    display: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -508,7 +508,7 @@ body.mobile.phone {
 | 
			
		||||
        &.expanded-widget-rules {
 | 
			
		||||
            .widget-rules-wrapper {
 | 
			
		||||
                min-height: 50px;
 | 
			
		||||
                height: auto;
 | 
			
		||||
                height: 100%; // Fix for Chrome 73 scrolling bug
 | 
			
		||||
                opacity: 1;
 | 
			
		||||
                pointer-events: inherit;
 | 
			
		||||
            }
 | 
			
		||||
@@ -520,7 +520,7 @@ body.mobile.phone {
 | 
			
		||||
            opacity: 0.3;
 | 
			
		||||
            pointer-events: none;
 | 
			
		||||
        }
 | 
			
		||||
        .t-message-widget-no-data {
 | 
			
		||||
        .js-summary-widget__message {
 | 
			
		||||
            display: flex;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -1177,79 +1177,6 @@ body.desktop {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************* WAIT SPINNERS */
 | 
			
		||||
@mixin  spinner($b: 5px, $c: $colorKey) {
 | 
			
		||||
    animation-name: rotation-centered;
 | 
			
		||||
    animation-duration: 0.5s;
 | 
			
		||||
    animation-iteration-count: infinite;
 | 
			
		||||
    animation-timing-function: linear;
 | 
			
		||||
    border-radius: 100%;
 | 
			
		||||
    box-sizing: border-box;
 | 
			
		||||
    border-color: rgba($c, 0.25);
 | 
			
		||||
    border-top-color: rgba($c, 1.0);
 | 
			
		||||
    border-style: solid;
 | 
			
		||||
    border-width: $b;
 | 
			
		||||
    display: block;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    left: 50%; top: 50%;
 | 
			
		||||
    transform-origin: center;
 | 
			
		||||
    transform: translate(-50%, -50%);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.wait-spinner {
 | 
			
		||||
    @include spinner($waitSpinnerBorderW, $colorKey);
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    z-index: 2;
 | 
			
		||||
    &.inline {
 | 
			
		||||
        display: inline-block !important;
 | 
			
		||||
        margin-right: $interiorMargin;
 | 
			
		||||
        position: relative !important;
 | 
			
		||||
        vertical-align: middle;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.loading {
 | 
			
		||||
    // Can be applied to any block element with height and width
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    &:before,
 | 
			
		||||
    &:after {
 | 
			
		||||
        content: '';
 | 
			
		||||
    }
 | 
			
		||||
    &:before {
 | 
			
		||||
        @include spinner($waitSpinnerBorderW, $colorLoadingFg);
 | 
			
		||||
        height: $waitSpinnerD; width: $waitSpinnerD;
 | 
			
		||||
        z-index: 10;
 | 
			
		||||
    }
 | 
			
		||||
    &:after {
 | 
			
		||||
        @include abs();
 | 
			
		||||
        background: $colorLoadingBg;
 | 
			
		||||
        display: block;
 | 
			
		||||
        z-index: 9;
 | 
			
		||||
    }
 | 
			
		||||
    &.tree-item.t-wait-node {
 | 
			
		||||
        $d: $waitSpinnerTreeD;
 | 
			
		||||
        $spinnerL: $interiorMargin + 19px + $d/2;
 | 
			
		||||
        padding-left: $spinnerL + $d/2 + $interiorMargin;
 | 
			
		||||
        .t-title-label {
 | 
			
		||||
            font-style: italic;
 | 
			
		||||
            opacity: 0.6;
 | 
			
		||||
        }
 | 
			
		||||
        &:before {
 | 
			
		||||
            height: $d;
 | 
			
		||||
            width: $d;
 | 
			
		||||
            border-width: 4px;
 | 
			
		||||
            left: $spinnerL;
 | 
			
		||||
        }
 | 
			
		||||
        &:after {
 | 
			
		||||
            display: none;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    &.c-loading--overlay {
 | 
			
		||||
        @include abs();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/******************************************************************* FLEX STYLES */
 | 
			
		||||
.l-flex-row,
 | 
			
		||||
.l-flex-col {
 | 
			
		||||
@@ -1514,6 +1441,10 @@ body.desktop {
 | 
			
		||||
    display: contents;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
mct-container {
 | 
			
		||||
    display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.overlay {
 | 
			
		||||
    .outer-holder {
 | 
			
		||||
        background: $colorMenuBg;
 | 
			
		||||
@@ -1579,3 +1510,157 @@ body.desktop {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.abs {
 | 
			
		||||
    position: absolute;
 | 
			
		||||
    top: 0;
 | 
			
		||||
    right: 0;
 | 
			
		||||
    bottom: 0;
 | 
			
		||||
    left: 0;
 | 
			
		||||
    height: auto;
 | 
			
		||||
    width: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code {
 | 
			
		||||
    font-family: "Lucida Console", monospace;
 | 
			
		||||
    font-size: 0.7em;
 | 
			
		||||
    line-height: 150%;
 | 
			
		||||
    white-space: pre;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.codehilite {
 | 
			
		||||
    @extend .code;
 | 
			
		||||
    background-color: rgba($colorBodyFg, 0.1);
 | 
			
		||||
    padding: 1em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.s-status-missing {
 | 
			
		||||
    // Labels. Expects .s-status-missing to be applied to mct-representation that contains
 | 
			
		||||
    .t-object-label .t-item-icon:before {
 | 
			
		||||
        content: $glyph-icon-object-unknown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Item, grid item. Expects .s-status-missing to be applied to mct-representation that contains .item.grid-item
 | 
			
		||||
    .item .t-item-icon-glyph:before {
 | 
			
		||||
        content: $glyph-icon-object-unknown;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Object header. Expects .s-status-missing to be applied to mct-representation.object-header
 | 
			
		||||
    &.object-header {
 | 
			
		||||
        .type-icon:before {
 | 
			
		||||
            content: $glyph-icon-object-unknown;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Tree item. Expects .s-status-missing to be applied to .tree-item,
 | 
			
		||||
    // and mct-representation.search-item
 | 
			
		||||
    &.tree-item,
 | 
			
		||||
    &.search-item {
 | 
			
		||||
        > .rep-object-label .t-item-icon:before {
 | 
			
		||||
            content: $glyph-icon-object-unknown;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.align-right {
 | 
			
		||||
    text-align: right;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.centered {
 | 
			
		||||
    text-align: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-selection {
 | 
			
		||||
    // aka selection = "None". Used in palettes and their menu buttons.
 | 
			
		||||
    $c: red;
 | 
			
		||||
    $s: 48%;
 | 
			
		||||
    $e: 52%;
 | 
			
		||||
    background-image: linear-gradient(-45deg,
 | 
			
		||||
            transparent $s - 5%,
 | 
			
		||||
            $c $s,
 | 
			
		||||
            $c $e,
 | 
			
		||||
            transparent $e + 5%
 | 
			
		||||
    );
 | 
			
		||||
    box-shadow:inset rgba(black, 0.3) 0 0 0 1px;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    background-size: contain;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.scrolling,
 | 
			
		||||
.scroll {
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.vscroll {
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
    overflow-y: auto;
 | 
			
		||||
    &.scroll-pad {
 | 
			
		||||
        padding-right: $interiorMargin;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.vscroll--persist {
 | 
			
		||||
    overflow-x: hidden;
 | 
			
		||||
    overflow-y: scroll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.slidable {
 | 
			
		||||
    cursor: move; // Fallback
 | 
			
		||||
    cursor: grab;
 | 
			
		||||
    cursor: -moz-grab;
 | 
			
		||||
    cursor: -webkit-grab;
 | 
			
		||||
    &.horz {
 | 
			
		||||
        cursor: col-resize;
 | 
			
		||||
    }
 | 
			
		||||
    &.vert {
 | 
			
		||||
        cursor: row-resize;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.no-margin {
 | 
			
		||||
    margin: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ds {
 | 
			
		||||
    box-shadow: rgba(#000, 0.7) 0 4px 10px 2px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.capitalize {
 | 
			
		||||
    text-transform: capitalize;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hide,
 | 
			
		||||
.hidden,
 | 
			
		||||
.t-main-view .hide-in-t-main-view {
 | 
			
		||||
    display: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.hide-nice {
 | 
			
		||||
    opacity: 0;
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.invisible {
 | 
			
		||||
    display: block;
 | 
			
		||||
    visibility: hidden;
 | 
			
		||||
    height: 0;
 | 
			
		||||
    padding: 0;
 | 
			
		||||
    border: 0;
 | 
			
		||||
    margin: 0 !important;
 | 
			
		||||
    transform: scale(0);
 | 
			
		||||
    pointer-events: none;
 | 
			
		||||
    position: absolute;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.sep {
 | 
			
		||||
    color: rgba(#fff, 0.2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.comma-list span {
 | 
			
		||||
    &:not(:first-child) {
 | 
			
		||||
        &:before {
 | 
			
		||||
            content: ', ';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,12 @@ table {
 | 
			
		||||
    width: 100%;
 | 
			
		||||
 | 
			
		||||
    thead {
 | 
			
		||||
        background: $colorTabHeaderBg;
 | 
			
		||||
        th + th {
 | 
			
		||||
            border-left: 1px solid $colorTabHeaderBorder;
 | 
			
		||||
        th {
 | 
			
		||||
            background: $colorTabHeaderBg;
 | 
			
		||||
 | 
			
		||||
            + th {
 | 
			
		||||
                border-left: 1px solid $colorTabHeaderBorder;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -46,6 +49,8 @@ table {
 | 
			
		||||
    td {
 | 
			
		||||
        vertical-align: top;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    a { color: $colorBtnMajorBg; }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
div.c-table {
 | 
			
		||||
 
 | 
			
		||||
@@ -142,7 +142,7 @@ export default {
 | 
			
		||||
            this.applySearch(this.currentSearch);
 | 
			
		||||
        },
 | 
			
		||||
        removeElement(identifier) {
 | 
			
		||||
            let keyString = this.openmct.objects.makeKeyString(element.identifier);
 | 
			
		||||
            let keyString = this.openmct.objects.makeKeyString(identifier);
 | 
			
		||||
            delete this.elementsCache[keyString];
 | 
			
		||||
            this.applySearch(this.currentSearch);
 | 
			
		||||
        },
 | 
			
		||||
 
 | 
			
		||||
@@ -95,7 +95,7 @@
 | 
			
		||||
            .l-pane__contents {
 | 
			
		||||
                display: flex;
 | 
			
		||||
                flex-flow: column nowrap;
 | 
			
		||||
                overflow: auto;
 | 
			
		||||
                overflow-x: hidden;
 | 
			
		||||
 | 
			
		||||
                > * {
 | 
			
		||||
                    flex: 0 0 auto;
 | 
			
		||||
@@ -242,7 +242,10 @@
 | 
			
		||||
 | 
			
		||||
    .is-editing {
 | 
			
		||||
        .l-shell__main-container {
 | 
			
		||||
            $m: 3px;
 | 
			
		||||
            box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdw;
 | 
			
		||||
            margin-left: $m;
 | 
			
		||||
            margin-right: $m;
 | 
			
		||||
 | 
			
		||||
            &[s-selected] {
 | 
			
		||||
                // Provide a clearer selection context articulation for the main edit area
 | 
			
		||||
 
 | 
			
		||||
@@ -9,15 +9,15 @@
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <!-- loading -->
 | 
			
		||||
        <span v-if="isLoading"
 | 
			
		||||
            class="loading">
 | 
			
		||||
        </span>
 | 
			
		||||
        <div class="c-tree-and-search__loading loading"
 | 
			
		||||
            v-if="isLoading"></div>
 | 
			
		||||
        <!-- end loading -->
 | 
			
		||||
 | 
			
		||||
        <div class="c-tree-and-search__no-results" v-if="treeItems.length === 0">
 | 
			
		||||
            No results found
 | 
			
		||||
        </div>
 | 
			
		||||
        <ul class="c-tree-and-search__tree c-tree">
 | 
			
		||||
        <ul class="c-tree-and-search__tree c-tree"
 | 
			
		||||
            v-if="!isLoading">
 | 
			
		||||
            <tree-item v-for="treeItem in treeItems"
 | 
			
		||||
                       :key="treeItem.id"
 | 
			
		||||
                       :node="treeItem">
 | 
			
		||||
@@ -41,6 +41,10 @@
 | 
			
		||||
            flex: 0 0 auto;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &__loading {
 | 
			
		||||
            flex: 1 1 auto;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        &__no-results {
 | 
			
		||||
            font-style: italic;
 | 
			
		||||
            opacity: 0.6;
 | 
			
		||||
@@ -54,10 +58,16 @@
 | 
			
		||||
 | 
			
		||||
    .c-tree {
 | 
			
		||||
        @include userSelectNone();
 | 
			
		||||
        height: 100%; // Chrome 73 overflow bug fix
 | 
			
		||||
        overflow-x: hidden;
 | 
			
		||||
        overflow-y: auto;
 | 
			
		||||
        padding-right: $interiorMargin;
 | 
			
		||||
 | 
			
		||||
        li {
 | 
			
		||||
            position: relative;
 | 
			
		||||
            &.c-tree__item-h { display: block; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .c-tree {
 | 
			
		||||
            margin-left: 15px;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -11,14 +11,12 @@
 | 
			
		||||
            </object-label>
 | 
			
		||||
        </div>
 | 
			
		||||
        <ul v-if="expanded" class="c-tree">
 | 
			
		||||
 | 
			
		||||
            <!-- loading -->
 | 
			
		||||
            <li
 | 
			
		||||
                class="loading"
 | 
			
		||||
            <li class="c-tree__item-h"
 | 
			
		||||
                v-if="isLoading && !loaded">
 | 
			
		||||
                <div class="c-tree__item loading">
 | 
			
		||||
                    <span class="c-tree__item__label">Loading...</span>
 | 
			
		||||
                </div>
 | 
			
		||||
            </li>
 | 
			
		||||
            <!-- end loading -->
 | 
			
		||||
 | 
			
		||||
            <tree-item v-for="child in children"
 | 
			
		||||
                       :key="child.id"
 | 
			
		||||
                       :node="child">
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user