Compare commits
	
		
			10 Commits
		
	
	
		
			log-plots-
			...
			fix-bargra
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					bfa65a8b22 | ||
| 
						 | 
					2b2ecb7791 | ||
| 
						 | 
					a6e8f76b55 | ||
| 
						 | 
					271f8ed38f | ||
| 
						 | 
					650f84e95c | ||
| 
						 | 
					da1fa0b095 | ||
| 
						 | 
					b70af5a1bb | ||
| 
						 | 
					cc1a5ef1dd | ||
| 
						 | 
					0af21632db | ||
| 
						 | 
					e2f1ff5442 | 
@@ -44,9 +44,11 @@ define(
 | 
			
		||||
                        setText(result.name);
 | 
			
		||||
                        scope.ngModel[scope.field] = result;
 | 
			
		||||
                        control.$setValidity("file-input", true);
 | 
			
		||||
                        scope.$digest();
 | 
			
		||||
                    }, function () {
 | 
			
		||||
                        setText('Select File');
 | 
			
		||||
                        control.$setValidity("file-input", false);
 | 
			
		||||
                        scope.$digest();
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								src/api/objects/ConflictError.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								src/api/objects/ConflictError.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
export default class ConflictError extends Error {
 | 
			
		||||
}
 | 
			
		||||
@@ -26,6 +26,7 @@ import RootRegistry from './RootRegistry';
 | 
			
		||||
import RootObjectProvider from './RootObjectProvider';
 | 
			
		||||
import EventEmitter from 'EventEmitter';
 | 
			
		||||
import InterceptorRegistry from './InterceptorRegistry';
 | 
			
		||||
import ConflictError from './ConflictError';
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Utilities for loading, saving, and manipulating domain objects.
 | 
			
		||||
@@ -34,6 +35,7 @@ import InterceptorRegistry from './InterceptorRegistry';
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
function ObjectAPI(typeRegistry, openmct) {
 | 
			
		||||
    this.openmct = openmct;
 | 
			
		||||
    this.typeRegistry = typeRegistry;
 | 
			
		||||
    this.eventEmitter = new EventEmitter();
 | 
			
		||||
    this.providers = {};
 | 
			
		||||
@@ -47,6 +49,10 @@ function ObjectAPI(typeRegistry, openmct) {
 | 
			
		||||
    this.interceptorRegistry = new InterceptorRegistry();
 | 
			
		||||
 | 
			
		||||
    this.SYNCHRONIZED_OBJECT_TYPES = ['notebook', 'plan'];
 | 
			
		||||
 | 
			
		||||
    this.errors = {
 | 
			
		||||
        Conflict: ConflictError
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -181,6 +187,7 @@ ObjectAPI.prototype.get = function (identifier, abortSignal) {
 | 
			
		||||
 | 
			
		||||
    let objectPromise = provider.get(identifier, abortSignal).then(result => {
 | 
			
		||||
        delete this.cache[keystring];
 | 
			
		||||
 | 
			
		||||
        result = this.applyGetInterceptors(identifier, result);
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
@@ -285,6 +292,7 @@ ObjectAPI.prototype.isPersistable = function (idOrKeyString) {
 | 
			
		||||
ObjectAPI.prototype.save = function (domainObject) {
 | 
			
		||||
    let provider = this.getProvider(domainObject.identifier);
 | 
			
		||||
    let savedResolve;
 | 
			
		||||
    let savedReject;
 | 
			
		||||
    let result;
 | 
			
		||||
 | 
			
		||||
    if (!this.isPersistable(domainObject.identifier)) {
 | 
			
		||||
@@ -294,14 +302,18 @@ ObjectAPI.prototype.save = function (domainObject) {
 | 
			
		||||
    } else {
 | 
			
		||||
        const persistedTime = Date.now();
 | 
			
		||||
        if (domainObject.persisted === undefined) {
 | 
			
		||||
            result = new Promise((resolve) => {
 | 
			
		||||
            result = new Promise((resolve, reject) => {
 | 
			
		||||
                savedResolve = resolve;
 | 
			
		||||
                savedReject = reject;
 | 
			
		||||
            });
 | 
			
		||||
            domainObject.persisted = persistedTime;
 | 
			
		||||
            provider.create(domainObject).then((response) => {
 | 
			
		||||
                this.mutate(domainObject, 'persisted', persistedTime);
 | 
			
		||||
                savedResolve(response);
 | 
			
		||||
            });
 | 
			
		||||
            provider.create(domainObject)
 | 
			
		||||
                .then((response) => {
 | 
			
		||||
                    this.mutate(domainObject, 'persisted', persistedTime);
 | 
			
		||||
                    savedResolve(response);
 | 
			
		||||
                }).catch((error) => {
 | 
			
		||||
                    savedReject(error);
 | 
			
		||||
                });
 | 
			
		||||
        } else {
 | 
			
		||||
            domainObject.persisted = persistedTime;
 | 
			
		||||
            this.mutate(domainObject, 'persisted', persistedTime);
 | 
			
		||||
 
 | 
			
		||||
@@ -130,8 +130,13 @@ export class TelemetryCollection extends EventEmitter {
 | 
			
		||||
        this.options.onPartialResponse = this._processNewTelemetry.bind(this);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (this.requestAbort) {
 | 
			
		||||
                this.requestAbort.abort();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.requestAbort = new AbortController();
 | 
			
		||||
            this.options.signal = this.requestAbort.signal;
 | 
			
		||||
            this.emit('requestStarted');
 | 
			
		||||
            historicalData = await this.historicalProvider.request(this.domainObject, this.options);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (error.name !== 'AbortError') {
 | 
			
		||||
@@ -140,6 +145,7 @@ export class TelemetryCollection extends EventEmitter {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.emit('requestEnded');
 | 
			
		||||
        this.requestAbort = undefined;
 | 
			
		||||
 | 
			
		||||
        this._processNewTelemetry(historicalData);
 | 
			
		||||
 
 | 
			
		||||
@@ -41,7 +41,6 @@ const DEFAULTS = [
 | 
			
		||||
    'platform/forms',
 | 
			
		||||
    'platform/identity',
 | 
			
		||||
    'platform/persistence/aggregator',
 | 
			
		||||
    'platform/persistence/queue',
 | 
			
		||||
    'platform/policy',
 | 
			
		||||
    'platform/entanglement',
 | 
			
		||||
    'platform/search',
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,7 @@ describe('the plugin', function () {
 | 
			
		||||
    let openmct;
 | 
			
		||||
    let composition;
 | 
			
		||||
 | 
			
		||||
    beforeEach((done) => {
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
 | 
			
		||||
        openmct = createOpenMct();
 | 
			
		||||
 | 
			
		||||
@@ -47,11 +47,6 @@ describe('the plugin', function () {
 | 
			
		||||
            }
 | 
			
		||||
        }));
 | 
			
		||||
 | 
			
		||||
        openmct.on('start', done);
 | 
			
		||||
        openmct.startHeadless();
 | 
			
		||||
 | 
			
		||||
        composition = openmct.composition.get({identifier});
 | 
			
		||||
 | 
			
		||||
        spyOn(couchPlugin.couchProvider, 'getObjectsByFilter').and.returnValue(Promise.resolve([
 | 
			
		||||
            {
 | 
			
		||||
                identifier: {
 | 
			
		||||
@@ -66,6 +61,19 @@ describe('the plugin', function () {
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        ]));
 | 
			
		||||
 | 
			
		||||
        spyOn(couchPlugin.couchProvider, "get").and.callFake((id) => {
 | 
			
		||||
            return Promise.resolve({
 | 
			
		||||
                identifier: id
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve) => {
 | 
			
		||||
            openmct.once('start', resolve);
 | 
			
		||||
            openmct.startHeadless();
 | 
			
		||||
        }).then(() => {
 | 
			
		||||
            composition = openmct.composition.get({identifier});
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    afterEach(() => {
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,8 @@ describe('the plugin', function () {
 | 
			
		||||
 | 
			
		||||
        conditionSetDefinition.initialize(mockConditionSetDomainObject);
 | 
			
		||||
 | 
			
		||||
        spyOn(openmct.objects, "save").and.returnValue(Promise.resolve(true));
 | 
			
		||||
 | 
			
		||||
        openmct.on('start', done);
 | 
			
		||||
        openmct.startHeadless();
 | 
			
		||||
    });
 | 
			
		||||
 
 | 
			
		||||
@@ -159,7 +159,7 @@ export default {
 | 
			
		||||
            let image = { ...datum };
 | 
			
		||||
            image.formattedTime = this.formatTime(datum);
 | 
			
		||||
            image.url = this.formatImageUrl(datum);
 | 
			
		||||
            image.time = datum[this.timeKey];
 | 
			
		||||
            image.time = this.parseTime(image.formattedTime);
 | 
			
		||||
            image.imageDownloadName = this.getImageDownloadName(datum);
 | 
			
		||||
 | 
			
		||||
            return image;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								src/plugins/notebook/monkeyPatchObjectAPIForNotebooks.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/plugins/notebook/monkeyPatchObjectAPIForNotebooks.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
import {NOTEBOOK_TYPE} from './notebook-constants';
 | 
			
		||||
 | 
			
		||||
export default function (openmct) {
 | 
			
		||||
    const apiSave = openmct.objects.save.bind(openmct.objects);
 | 
			
		||||
 | 
			
		||||
    openmct.objects.save = async (domainObject) => {
 | 
			
		||||
        if (domainObject.type !== NOTEBOOK_TYPE) {
 | 
			
		||||
            return apiSave(domainObject);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const localMutable = openmct.objects._toMutable(domainObject);
 | 
			
		||||
        let result;
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            result = await apiSave(localMutable);
 | 
			
		||||
        } catch (error) {
 | 
			
		||||
            if (error instanceof openmct.objects.errors.Conflict) {
 | 
			
		||||
                result = resolveConflicts(localMutable, openmct);
 | 
			
		||||
            } else {
 | 
			
		||||
                result = Promise.reject(error);
 | 
			
		||||
            }
 | 
			
		||||
        } finally {
 | 
			
		||||
            openmct.objects.destroyMutable(localMutable);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return result;
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function resolveConflicts(localMutable, openmct) {
 | 
			
		||||
    return openmct.objects.getMutable(localMutable.identifier).then((remoteMutable) => {
 | 
			
		||||
        const localEntries = localMutable.configuration.entries;
 | 
			
		||||
        remoteMutable.$refresh(remoteMutable);
 | 
			
		||||
        applyLocalEntries(remoteMutable, localEntries);
 | 
			
		||||
 | 
			
		||||
        openmct.objects.destroyMutable(remoteMutable);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function applyLocalEntries(mutable, entries) {
 | 
			
		||||
    Object.entries(entries).forEach(([sectionKey, pagesInSection]) => {
 | 
			
		||||
        Object.entries(pagesInSection).forEach(([pageKey, localEntries]) => {
 | 
			
		||||
            const remoteEntries = mutable.configuration.entries[sectionKey][pageKey];
 | 
			
		||||
            const mergedEntries = [].concat(remoteEntries);
 | 
			
		||||
            let shouldMutate = false;
 | 
			
		||||
 | 
			
		||||
            const locallyAddedEntries = _.differenceBy(localEntries, remoteEntries, 'id');
 | 
			
		||||
            const locallyModifiedEntries = _.differenceWith(localEntries, remoteEntries, (localEntry, remoteEntry) => {
 | 
			
		||||
                return localEntry.id === remoteEntry.id && localEntry.text === remoteEntry.text;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            locallyAddedEntries.forEach((localEntry) => {
 | 
			
		||||
                mergedEntries.push(localEntry);
 | 
			
		||||
                shouldMutate = true;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            locallyModifiedEntries.forEach((locallyModifiedEntry) => {
 | 
			
		||||
                let mergedEntry = mergedEntries.find(entry => entry.id === locallyModifiedEntry.id);
 | 
			
		||||
                if (mergedEntry !== undefined) {
 | 
			
		||||
                    mergedEntry.text = locallyModifiedEntry.text;
 | 
			
		||||
                    shouldMutate = true;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            if (shouldMutate) {
 | 
			
		||||
                mutable.$set(`configuration.entries.${sectionKey}.${pageKey}`, mergedEntries);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
@@ -2,6 +2,7 @@ import CopyToNotebookAction from './actions/CopyToNotebookAction';
 | 
			
		||||
import Notebook from './components/Notebook.vue';
 | 
			
		||||
import NotebookSnapshotIndicator from './components/NotebookSnapshotIndicator.vue';
 | 
			
		||||
import SnapshotContainer from './snapshot-container';
 | 
			
		||||
import monkeyPatchObjectAPIForNotebooks from './monkeyPatchObjectAPIForNotebooks.js';
 | 
			
		||||
 | 
			
		||||
import { notebookImageMigration } from '../notebook/utils/notebook-migration';
 | 
			
		||||
import { NOTEBOOK_TYPE } from './notebook-constants';
 | 
			
		||||
@@ -165,5 +166,7 @@ export default function NotebookPlugin() {
 | 
			
		||||
                return domainObject;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        monkeyPatchObjectAPIForNotebooks(openmct);
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -154,6 +154,8 @@ describe("Notebook plugin:", () => {
 | 
			
		||||
            testObjectProvider.get.and.returnValue(Promise.resolve(notebookViewObject));
 | 
			
		||||
            openmct.objects.addProvider('test-namespace', testObjectProvider);
 | 
			
		||||
            testObjectProvider.observe.and.returnValue(() => {});
 | 
			
		||||
            testObjectProvider.create.and.returnValue(Promise.resolve(true));
 | 
			
		||||
            testObjectProvider.update.and.returnValue(Promise.resolve(true));
 | 
			
		||||
 | 
			
		||||
            return openmct.objects.getMutable(notebookViewObject.identifier).then((mutableObject) => {
 | 
			
		||||
                mutableNotebookObject = mutableObject;
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,7 @@ export function addNotebookEntry(openmct, domainObject, notebookStorage, embed =
 | 
			
		||||
    const newEntries = addEntryIntoPage(notebookStorage, entries, entry);
 | 
			
		||||
 | 
			
		||||
    addDefaultClass(domainObject, openmct);
 | 
			
		||||
    openmct.objects.mutate(domainObject, 'configuration.entries', newEntries);
 | 
			
		||||
    domainObject.configuration.entries = newEntries;
 | 
			
		||||
 | 
			
		||||
    return id;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,12 +15,16 @@
 | 
			
		||||
 | 
			
		||||
        port.onmessage = async function (event) {
 | 
			
		||||
            if (event.data.request === 'close') {
 | 
			
		||||
                console.log('Closing connection');
 | 
			
		||||
                connections.splice(event.data.connectionId - 1, 1);
 | 
			
		||||
                if (connections.length <= 0) {
 | 
			
		||||
                    // abort any outstanding requests if there's nobody listening to it.
 | 
			
		||||
                    controller.abort();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                console.log('Closed.');
 | 
			
		||||
                connected = false;
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -29,68 +33,9 @@
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                connected = true;
 | 
			
		||||
 | 
			
		||||
                let url = event.data.url;
 | 
			
		||||
                let body = event.data.body;
 | 
			
		||||
                let error = false;
 | 
			
		||||
                // feed=continuous maintains an indefinitely open connection with a keep-alive of HEARTBEAT milliseconds until this client closes the connection
 | 
			
		||||
                // style=main_only returns only the current winning revision of the document
 | 
			
		||||
 | 
			
		||||
                const response = await fetch(url, {
 | 
			
		||||
                    method: 'POST',
 | 
			
		||||
                    headers: {
 | 
			
		||||
                        "Content-Type": 'application/json'
 | 
			
		||||
                    },
 | 
			
		||||
                    signal,
 | 
			
		||||
                    body
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                let reader;
 | 
			
		||||
 | 
			
		||||
                if (response.body === undefined) {
 | 
			
		||||
                    error = true;
 | 
			
		||||
                } else {
 | 
			
		||||
                    reader = response.body.getReader();
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                while (!error) {
 | 
			
		||||
                    const {done, value} = await reader.read();
 | 
			
		||||
                    //done is true when we lose connection with the provider
 | 
			
		||||
                    if (done) {
 | 
			
		||||
                        error = true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (value) {
 | 
			
		||||
                        let chunk = new Uint8Array(value.length);
 | 
			
		||||
                        chunk.set(value, 0);
 | 
			
		||||
                        const decodedChunk = new TextDecoder("utf-8").decode(chunk).split('\n');
 | 
			
		||||
                        if (decodedChunk.length && decodedChunk[decodedChunk.length - 1] === '') {
 | 
			
		||||
                            decodedChunk.forEach((doc, index) => {
 | 
			
		||||
                                try {
 | 
			
		||||
                                    if (doc) {
 | 
			
		||||
                                        const objectChanges = JSON.parse(doc);
 | 
			
		||||
                                        connections.forEach(function (connection) {
 | 
			
		||||
                                            connection.postMessage({
 | 
			
		||||
                                                objectChanges
 | 
			
		||||
                                            });
 | 
			
		||||
                                        });
 | 
			
		||||
                                    }
 | 
			
		||||
                                } catch (decodeError) {
 | 
			
		||||
                                    //do nothing;
 | 
			
		||||
                                    console.log(decodeError);
 | 
			
		||||
                                }
 | 
			
		||||
                            });
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (error) {
 | 
			
		||||
                    port.postMessage({
 | 
			
		||||
                        error
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
                do {
 | 
			
		||||
                    await self.listenForChanges(event.data.url, event.data.body, port);
 | 
			
		||||
                } while (connected);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
@@ -103,4 +48,64 @@
 | 
			
		||||
        console.log('Error on feed');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    self.listenForChanges = async function (url, body, port) {
 | 
			
		||||
        connected = true;
 | 
			
		||||
        let error = false;
 | 
			
		||||
        // feed=continuous maintains an indefinitely open connection with a keep-alive of HEARTBEAT milliseconds until this client closes the connection
 | 
			
		||||
        // style=main_only returns only the current winning revision of the document
 | 
			
		||||
 | 
			
		||||
        console.log('Opening changes feed connection.');
 | 
			
		||||
        const response = await fetch(url, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            headers: {
 | 
			
		||||
                "Content-Type": 'application/json'
 | 
			
		||||
            },
 | 
			
		||||
            signal,
 | 
			
		||||
            body
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        let reader;
 | 
			
		||||
 | 
			
		||||
        if (response.body === undefined) {
 | 
			
		||||
            error = true;
 | 
			
		||||
        } else {
 | 
			
		||||
            reader = response.body.getReader();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        while (!error) {
 | 
			
		||||
            const {done, value} = await reader.read();
 | 
			
		||||
            //done is true when we lose connection with the provider
 | 
			
		||||
            if (done) {
 | 
			
		||||
                error = true;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (value) {
 | 
			
		||||
                let chunk = new Uint8Array(value.length);
 | 
			
		||||
                chunk.set(value, 0);
 | 
			
		||||
                const decodedChunk = new TextDecoder("utf-8").decode(chunk).split('\n');
 | 
			
		||||
                console.log('Received chunk');
 | 
			
		||||
                if (decodedChunk.length && decodedChunk[decodedChunk.length - 1] === '') {
 | 
			
		||||
                    decodedChunk.forEach((doc, index) => {
 | 
			
		||||
                        try {
 | 
			
		||||
                            if (doc) {
 | 
			
		||||
                                const objectChanges = JSON.parse(doc);
 | 
			
		||||
                                connections.forEach(function (connection) {
 | 
			
		||||
                                    connection.postMessage({
 | 
			
		||||
                                        objectChanges
 | 
			
		||||
                                    });
 | 
			
		||||
                                });
 | 
			
		||||
                            }
 | 
			
		||||
                        } catch (decodeError) {
 | 
			
		||||
                            //do nothing;
 | 
			
		||||
                            console.log(decodeError);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        console.log('Done reading changes feed');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
}());
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ const ID = "_id";
 | 
			
		||||
const HEARTBEAT = 50000;
 | 
			
		||||
const ALL_DOCS = "_all_docs?include_docs=true";
 | 
			
		||||
 | 
			
		||||
export default class CouchObjectProvider {
 | 
			
		||||
class CouchObjectProvider {
 | 
			
		||||
    constructor(openmct, options, namespace) {
 | 
			
		||||
        options = this._normalize(options);
 | 
			
		||||
        this.openmct = openmct;
 | 
			
		||||
@@ -74,13 +74,6 @@ export default class CouchObjectProvider {
 | 
			
		||||
        if (event.data.type === 'connection') {
 | 
			
		||||
            this.changesFeedSharedWorkerConnectionId = event.data.connectionId;
 | 
			
		||||
        } else {
 | 
			
		||||
            const error = event.data.error;
 | 
			
		||||
            if (error && Object.keys(this.observers).length > 0) {
 | 
			
		||||
                this.observeObjectChanges();
 | 
			
		||||
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            let objectChanges = event.data.objectChanges;
 | 
			
		||||
            objectChanges.identifier = {
 | 
			
		||||
                namespace: this.namespace,
 | 
			
		||||
@@ -126,11 +119,12 @@ export default class CouchObjectProvider {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return fetch(this.url + '/' + subPath, fetchOptions)
 | 
			
		||||
            .then(response => response.json())
 | 
			
		||||
            .then(function (response) {
 | 
			
		||||
                return response;
 | 
			
		||||
            }, function () {
 | 
			
		||||
                return undefined;
 | 
			
		||||
            .then((response) => {
 | 
			
		||||
                if (response.status === CouchObjectProvider.HTTP_CONFLICT) {
 | 
			
		||||
                    throw new this.openmct.objects.errors.Conflict(`Conflict persisting ${fetchOptions.body.name}`);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return response.json();
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -561,12 +555,18 @@ export default class CouchObjectProvider {
 | 
			
		||||
        let intermediateResponse = this.getIntermediateResponse();
 | 
			
		||||
        const key = model.identifier.key;
 | 
			
		||||
        this.enqueueObject(key, model, intermediateResponse);
 | 
			
		||||
        this.objectQueue[key].pending = true;
 | 
			
		||||
        const queued = this.objectQueue[key].dequeue();
 | 
			
		||||
        let document = new CouchDocument(key, queued.model);
 | 
			
		||||
        this.request(key, "PUT", document).then((response) => {
 | 
			
		||||
            this.checkResponse(response, queued.intermediateResponse, key);
 | 
			
		||||
        });
 | 
			
		||||
        if (!this.objectQueue[key].pending) {
 | 
			
		||||
            this.objectQueue[key].pending = true;
 | 
			
		||||
            const queued = this.objectQueue[key].dequeue();
 | 
			
		||||
            let document = new CouchDocument(key, queued.model);
 | 
			
		||||
            this.request(key, "PUT", document).then((response) => {
 | 
			
		||||
                console.log('create check response', key);
 | 
			
		||||
                this.checkResponse(response, queued.intermediateResponse, key);
 | 
			
		||||
            }).catch(error => {
 | 
			
		||||
                queued.intermediateResponse.reject(error);
 | 
			
		||||
                this.objectQueue[key].pending = false;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return intermediateResponse.promise;
 | 
			
		||||
    }
 | 
			
		||||
@@ -581,6 +581,9 @@ export default class CouchObjectProvider {
 | 
			
		||||
            let document = new CouchDocument(key, queued.model, this.objectQueue[key].rev);
 | 
			
		||||
            this.request(key, "PUT", document).then((response) => {
 | 
			
		||||
                this.checkResponse(response, queued.intermediateResponse, key);
 | 
			
		||||
            }).catch((error) => {
 | 
			
		||||
                queued.intermediateResponse.reject(error);
 | 
			
		||||
                this.objectQueue[key].pending = false;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -594,3 +597,7 @@ export default class CouchObjectProvider {
 | 
			
		||||
        return intermediateResponse.promise;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CouchObjectProvider.HTTP_CONFLICT = 409;
 | 
			
		||||
 | 
			
		||||
export default CouchObjectProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -21,67 +21,57 @@
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
<div class="u-contents">
 | 
			
		||||
    <ul v-if="canEdit"
 | 
			
		||||
        class="l-inspector-part"
 | 
			
		||||
    <div v-if="canEdit"
 | 
			
		||||
         class="grid-row"
 | 
			
		||||
    >
 | 
			
		||||
        <h2 v-if="heading"
 | 
			
		||||
            :title="heading"
 | 
			
		||||
        >{{ heading }}</h2>
 | 
			
		||||
        <li class="grid-row">
 | 
			
		||||
            <div class="grid-cell label"
 | 
			
		||||
                 :title="editTitle"
 | 
			
		||||
            >{{ shortLabel }}</div>
 | 
			
		||||
            <div class="grid-cell value">
 | 
			
		||||
                <div class="c-click-swatch c-click-swatch--menu"
 | 
			
		||||
                     @click="toggleSwatch()"
 | 
			
		||||
        <div class="grid-cell label"
 | 
			
		||||
             :title="editTitle"
 | 
			
		||||
        >{{ shortLabel }}</div>
 | 
			
		||||
        <div class="grid-cell value">
 | 
			
		||||
            <div class="c-click-swatch c-click-swatch--menu"
 | 
			
		||||
                 @click="toggleSwatch()"
 | 
			
		||||
            >
 | 
			
		||||
                <span class="c-color-swatch"
 | 
			
		||||
                      :style="{ background: currentColor }"
 | 
			
		||||
                >
 | 
			
		||||
                    <span class="c-color-swatch"
 | 
			
		||||
                          :style="{ background: currentColor }"
 | 
			
		||||
                </span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="c-palette c-palette--color">
 | 
			
		||||
                <div v-show="swatchActive"
 | 
			
		||||
                     class="c-palette__items"
 | 
			
		||||
                >
 | 
			
		||||
                    <div v-for="group in colorPaletteGroups"
 | 
			
		||||
                         :key="group.id"
 | 
			
		||||
                         class="u-contents"
 | 
			
		||||
                    >
 | 
			
		||||
                    </span>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="c-palette c-palette--color">
 | 
			
		||||
                    <div v-show="swatchActive"
 | 
			
		||||
                         class="c-palette__items"
 | 
			
		||||
                    >
 | 
			
		||||
                        <div v-for="group in colorPaletteGroups"
 | 
			
		||||
                             :key="group.id"
 | 
			
		||||
                             class="u-contents"
 | 
			
		||||
                        <div v-for="color in group"
 | 
			
		||||
                             :key="color.id"
 | 
			
		||||
                             class="c-palette__item"
 | 
			
		||||
                             :class="{ 'selected': currentColor === color.hexString }"
 | 
			
		||||
                             :style="{ background: color.hexString }"
 | 
			
		||||
                             @click="setColor(color)"
 | 
			
		||||
                        >
 | 
			
		||||
                            <div v-for="color in group"
 | 
			
		||||
                                 :key="color.id"
 | 
			
		||||
                                 class="c-palette__item"
 | 
			
		||||
                                 :class="{ 'selected': currentColor === color.hexString }"
 | 
			
		||||
                                 :style="{ background: color.hexString }"
 | 
			
		||||
                                 @click="setColor(color)"
 | 
			
		||||
                            >
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </li>
 | 
			
		||||
    </ul>
 | 
			
		||||
    <ul v-else
 | 
			
		||||
        class="l-inspector-part"
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div v-else
 | 
			
		||||
         class="grid-row"
 | 
			
		||||
    >
 | 
			
		||||
        <h2 v-if="heading"
 | 
			
		||||
            :title="heading"
 | 
			
		||||
        >{{ heading }}</h2>
 | 
			
		||||
        <li class="grid-row">
 | 
			
		||||
            <div class="grid-cell label"
 | 
			
		||||
                 :title="viewTitle"
 | 
			
		||||
            >{{ shortLabel }}</div>
 | 
			
		||||
            <div class="grid-cell value">
 | 
			
		||||
                <span class="c-color-swatch"
 | 
			
		||||
                      :style="{
 | 
			
		||||
                          'background': currentColor
 | 
			
		||||
                      }"
 | 
			
		||||
                >
 | 
			
		||||
                </span>
 | 
			
		||||
            </div>
 | 
			
		||||
        </li>
 | 
			
		||||
    </ul>
 | 
			
		||||
        <div class="grid-cell label"
 | 
			
		||||
             :title="viewTitle"
 | 
			
		||||
        >{{ shortLabel }}</div>
 | 
			
		||||
        <div class="grid-cell value">
 | 
			
		||||
            <span class="c-color-swatch"
 | 
			
		||||
                  :style="{
 | 
			
		||||
                      'background': currentColor
 | 
			
		||||
                  }"
 | 
			
		||||
            >
 | 
			
		||||
            </span>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@@ -114,12 +104,6 @@ export default {
 | 
			
		||||
            default() {
 | 
			
		||||
                return 'Color';
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        heading: {
 | 
			
		||||
            type: String,
 | 
			
		||||
            default() {
 | 
			
		||||
                return '';
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    data() {
 | 
			
		||||
 
 | 
			
		||||
@@ -107,7 +107,7 @@ export default {
 | 
			
		||||
                };
 | 
			
		||||
                this.openmct.objects.mutate(
 | 
			
		||||
                    this.domainObject,
 | 
			
		||||
                    `configuration.barStyles[${this.key}]`,
 | 
			
		||||
                    `configuration.barStyles[${key}]`,
 | 
			
		||||
                    this.domainObject.configuration.barStyles[key]
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -33,9 +33,9 @@
 | 
			
		||||
    </li>
 | 
			
		||||
    <ColorSwatch v-if="expanded"
 | 
			
		||||
                 :current-color="currentColor"
 | 
			
		||||
                 title="Manually set the color for this bar graph."
 | 
			
		||||
                 edit-title="Manually set the color for this bar graph"
 | 
			
		||||
                 view-title="The color for this bar graph."
 | 
			
		||||
                 title="Manually set the color for this bar graph series."
 | 
			
		||||
                 edit-title="Manually set the color for this bar graph series"
 | 
			
		||||
                 view-title="The color for this bar graph series."
 | 
			
		||||
                 short-label="Color"
 | 
			
		||||
                 class="grid-properties"
 | 
			
		||||
                 @colorSet="setColor"
 | 
			
		||||
 
 | 
			
		||||
@@ -20,15 +20,13 @@
 | 
			
		||||
 at runtime from the About dialog for additional information.
 | 
			
		||||
-->
 | 
			
		||||
<template>
 | 
			
		||||
<div>
 | 
			
		||||
    <ul class="c-tree">
 | 
			
		||||
        <li v-for="series in domainObject.composition"
 | 
			
		||||
            :key="series.key"
 | 
			
		||||
        >
 | 
			
		||||
            <bar-graph-options :item="series" />
 | 
			
		||||
        </li>
 | 
			
		||||
    </ul>
 | 
			
		||||
</div>
 | 
			
		||||
<ul class="c-tree">
 | 
			
		||||
    <h2 title="Display properties for this object">Bar Graph Series</h2>
 | 
			
		||||
    <bar-graph-options v-for="series in domainObject.composition"
 | 
			
		||||
                       :key="series.key"
 | 
			
		||||
                       :item="series"
 | 
			
		||||
    />
 | 
			
		||||
</ul>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script>
 | 
			
		||||
 
 | 
			
		||||
@@ -60,18 +60,17 @@ define([
 | 
			
		||||
            this.addTelemetryObject = this.addTelemetryObject.bind(this);
 | 
			
		||||
            this.removeTelemetryObject = this.removeTelemetryObject.bind(this);
 | 
			
		||||
            this.removeTelemetryCollection = this.removeTelemetryCollection.bind(this);
 | 
			
		||||
            this.incrementOutstandingRequests = this.incrementOutstandingRequests.bind(this);
 | 
			
		||||
            this.decrementOutstandingRequests = this.decrementOutstandingRequests.bind(this);
 | 
			
		||||
            this.resetRowsFromAllData = this.resetRowsFromAllData.bind(this);
 | 
			
		||||
            this.isTelemetryObject = this.isTelemetryObject.bind(this);
 | 
			
		||||
            this.refreshData = this.refreshData.bind(this);
 | 
			
		||||
            this.updateFilters = this.updateFilters.bind(this);
 | 
			
		||||
            this.clearData = this.clearData.bind(this);
 | 
			
		||||
            this.buildOptionsFromConfiguration = this.buildOptionsFromConfiguration.bind(this);
 | 
			
		||||
 | 
			
		||||
            this.filterObserver = undefined;
 | 
			
		||||
 | 
			
		||||
            this.createTableRowCollections();
 | 
			
		||||
 | 
			
		||||
            openmct.time.on('bounds', this.refreshData);
 | 
			
		||||
            openmct.time.on('timeSystem', this.refreshData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
@@ -141,8 +140,6 @@ define([
 | 
			
		||||
            let columnMap = this.getColumnMapForObject(keyString);
 | 
			
		||||
            let limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
 | 
			
		||||
 | 
			
		||||
            this.incrementOutstandingRequests();
 | 
			
		||||
 | 
			
		||||
            const telemetryProcessor = this.getTelemetryProcessor(keyString, columnMap, limitEvaluator);
 | 
			
		||||
            const telemetryRemover = this.getTelemetryRemover();
 | 
			
		||||
 | 
			
		||||
@@ -151,13 +148,13 @@ define([
 | 
			
		||||
            this.telemetryCollections[keyString] = this.openmct.telemetry
 | 
			
		||||
                .requestCollection(telemetryObject, requestOptions);
 | 
			
		||||
 | 
			
		||||
            this.telemetryCollections[keyString].on('requestStarted', this.incrementOutstandingRequests);
 | 
			
		||||
            this.telemetryCollections[keyString].on('requestEnded', this.decrementOutstandingRequests);
 | 
			
		||||
            this.telemetryCollections[keyString].on('remove', telemetryRemover);
 | 
			
		||||
            this.telemetryCollections[keyString].on('add', telemetryProcessor);
 | 
			
		||||
            this.telemetryCollections[keyString].on('clear', this.tableRows.clear);
 | 
			
		||||
            this.telemetryCollections[keyString].on('clear', this.clearData);
 | 
			
		||||
            this.telemetryCollections[keyString].load();
 | 
			
		||||
 | 
			
		||||
            this.decrementOutstandingRequests();
 | 
			
		||||
 | 
			
		||||
            this.telemetryObjects[keyString] = {
 | 
			
		||||
                telemetryObject,
 | 
			
		||||
                keyString,
 | 
			
		||||
@@ -268,17 +265,6 @@ define([
 | 
			
		||||
            this.emit('object-removed', objectIdentifier);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        refreshData(bounds, isTick) {
 | 
			
		||||
            if (!isTick && this.tableRows.outstandingRequests === 0) {
 | 
			
		||||
                this.tableRows.clear();
 | 
			
		||||
                this.tableRows.sortBy({
 | 
			
		||||
                    key: this.openmct.time.timeSystem().key,
 | 
			
		||||
                    direction: 'asc'
 | 
			
		||||
                });
 | 
			
		||||
                this.tableRows.resubscribe();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        clearData() {
 | 
			
		||||
            this.tableRows.clear();
 | 
			
		||||
            this.emit('refresh');
 | 
			
		||||
@@ -378,9 +364,6 @@ define([
 | 
			
		||||
            let keystrings = Object.keys(this.telemetryCollections);
 | 
			
		||||
            keystrings.forEach(this.removeTelemetryCollection);
 | 
			
		||||
 | 
			
		||||
            this.openmct.time.off('bounds', this.refreshData);
 | 
			
		||||
            this.openmct.time.off('timeSystem', this.refreshData);
 | 
			
		||||
 | 
			
		||||
            if (this.filterObserver) {
 | 
			
		||||
                this.filterObserver();
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -125,7 +125,6 @@
 | 
			
		||||
    <div
 | 
			
		||||
        class="c-table c-telemetry-table c-table--filterable c-table--sortable has-control-bar u-style-receiver js-style-receiver"
 | 
			
		||||
        :class="{
 | 
			
		||||
            'loading': loading,
 | 
			
		||||
            'is-paused' : paused
 | 
			
		||||
        }"
 | 
			
		||||
    >
 | 
			
		||||
@@ -422,6 +421,14 @@ export default {
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    watch: {
 | 
			
		||||
        loading: {
 | 
			
		||||
            handler(isLoading) {
 | 
			
		||||
                if (this.viewActionsCollection) {
 | 
			
		||||
                    let action = isLoading ? 'disable' : 'enable';
 | 
			
		||||
                    this.viewActionsCollection[action](['export-csv-all']);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        },
 | 
			
		||||
        markedRows: {
 | 
			
		||||
            handler(newVal, oldVal) {
 | 
			
		||||
                this.$emit('marked-rows-updated', newVal, oldVal);
 | 
			
		||||
@@ -1020,6 +1027,12 @@ export default {
 | 
			
		||||
                this.viewActionsCollection.disable(['export-csv-marked', 'unmark-all-rows']);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this.loading) {
 | 
			
		||||
                this.viewActionsCollection.disable(['export-csv-all']);
 | 
			
		||||
            } else {
 | 
			
		||||
                this.viewActionsCollection.enable(['export-csv-all']);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (this.paused) {
 | 
			
		||||
                this.viewActionsCollection.hide(['pause-data']);
 | 
			
		||||
                this.viewActionsCollection.show(['play-data']);
 | 
			
		||||
 
 | 
			
		||||
@@ -88,7 +88,7 @@ export default {
 | 
			
		||||
            this.mutablePromise.then(() => {
 | 
			
		||||
                this.openmct.objects.destroyMutable(this.domainObject);
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
        } else if (this.domainObject.isMutable) {
 | 
			
		||||
            this.openmct.objects.destroyMutable(this.domainObject);
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 
 | 
			
		||||
@@ -49,6 +49,7 @@ describe("the inspector", () => {
 | 
			
		||||
 | 
			
		||||
    beforeEach((done) => {
 | 
			
		||||
        openmct = createOpenMct();
 | 
			
		||||
        spyOn(openmct.objects, 'save').and.returnValue(Promise.resolve(true));
 | 
			
		||||
        openmct.on('start', done);
 | 
			
		||||
        openmct.startHeadless();
 | 
			
		||||
    });
 | 
			
		||||
@@ -77,12 +78,12 @@ describe("the inspector", () => {
 | 
			
		||||
        expect(savedStylesViewComponent.$children[0].$children.length).toBe(0);
 | 
			
		||||
        stylesViewComponent.$children[0].saveStyle(mockStyle);
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
        return stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            expect(savedStylesViewComponent.$children[0].$children.length).toBe(1);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("should allow a saved style to be applied", () => {
 | 
			
		||||
    xit("should allow a saved style to be applied", () => {
 | 
			
		||||
        spyOn(openmct.editor, 'isEditing').and.returnValue(true);
 | 
			
		||||
 | 
			
		||||
        selection = mockTelemetryTableSelection;
 | 
			
		||||
@@ -91,12 +92,12 @@ describe("the inspector", () => {
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$children[0].saveStyle(mockStyle);
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
        return stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            const styleSelectorComponent = savedStylesViewComponent.$children[0].$children[0];
 | 
			
		||||
 | 
			
		||||
            styleSelectorComponent.selectStyle();
 | 
			
		||||
 | 
			
		||||
            savedStylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            return savedStylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
                const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
 | 
			
		||||
                const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
 | 
			
		||||
                const styles = styleEditorComponent.$children.filter(component => component.options.value === mockStyle.color);
 | 
			
		||||
@@ -147,7 +148,7 @@ describe("the inspector", () => {
 | 
			
		||||
        stylesViewComponent = createViewComponent(StylesView, selection, openmct);
 | 
			
		||||
        savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
        return stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
 | 
			
		||||
            const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
 | 
			
		||||
            const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
 | 
			
		||||
@@ -168,7 +169,7 @@ describe("the inspector", () => {
 | 
			
		||||
        stylesViewComponent = createViewComponent(StylesView, selection, openmct);
 | 
			
		||||
        savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
        return stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
 | 
			
		||||
            const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
 | 
			
		||||
            const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
 | 
			
		||||
@@ -185,7 +186,7 @@ describe("the inspector", () => {
 | 
			
		||||
        stylesViewComponent = createViewComponent(StylesView, selection, openmct);
 | 
			
		||||
        savedStylesViewComponent = createViewComponent(SavedStylesView, selection, openmct);
 | 
			
		||||
 | 
			
		||||
        stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
        return stylesViewComponent.$nextTick().then(() => {
 | 
			
		||||
            const styleEditorComponentIndex = stylesViewComponent.$children[0].$children.length - 1;
 | 
			
		||||
            const styleEditorComponent = stylesViewComponent.$children[0].$children[styleEditorComponentIndex];
 | 
			
		||||
            const saveStyleButtonIndex = styleEditorComponent.$children.length - 1;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user