Compare commits
	
		
			5 Commits
		
	
	
		
			table-pagi
			...
			v2.0.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 484226b229 | ||
|   | abfa971dd6 | ||
|   | 6d50dd571a | ||
|   | b58e38ee15 | ||
|   | d2923a672c | 
| @@ -22,14 +22,14 @@ | ||||
|  | ||||
| /* | ||||
| Collection of Visual Tests set to run in a default context. The tests within this suite | ||||
| are only meant to run against openmct's app.js started by `npm run start` within the  | ||||
| are only meant to run against openmct's app.js started by `npm run start` within the | ||||
| `./e2e/playwright-visual.config.js` file. | ||||
|  | ||||
| These should only use functional expect statements to verify assumptions about the state  | ||||
| These should only use functional expect statements to verify assumptions about the state | ||||
| in a test and not for functional verification of correctness. Visual tests are not supposed | ||||
| to "fail" on assertions. Instead, they should be used to detect changes between builds or branches. | ||||
|  | ||||
| Note: Larger testsuite sizes are OK due to the setup time associated with these tests.  | ||||
| Note: Larger testsuite sizes are OK due to the setup time associated with these tests. | ||||
| */ | ||||
|  | ||||
| const { test, expect } = require('@playwright/test'); | ||||
| @@ -111,3 +111,50 @@ test('Visual - Default Condition Widget', async ({ page }) => { | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Condition Widget'); | ||||
| }); | ||||
|  | ||||
| test.skip('Visual - Display layout items view', async ({ page }) => { | ||||
|     //Go to baseURL | ||||
|     await page.goto('/', { waitUntil: 'networkidle' }); | ||||
|  | ||||
|     //Click the Create button | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click text=Display Layout | ||||
|     await page.click('text=Display Layout'); | ||||
|  | ||||
|     // Click text=OK | ||||
|     await page.click('text=OK'); | ||||
|  | ||||
|     // Take a snapshot of the newly created Display Layout object | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Display Layout'); | ||||
|  | ||||
|     // Click text=Snapshot Save and Finish Editing Save and Continue Editing >> button >> nth=1 | ||||
|     await page.locator('text=Snapshot Save and Finish Editing Save and Continue Editing >> button').nth(1).click(); | ||||
|  | ||||
|     // Click text=Save and Finish Editing | ||||
|     await page.locator('text=Save and Finish Editing').click(); | ||||
|  | ||||
|     //Click the Create button | ||||
|     await page.click('button:has-text("Create")'); | ||||
|  | ||||
|     // Click text=Sine Wave Generator | ||||
|     await page.click('text=Sine Wave Generator'); | ||||
|  | ||||
|     // Click text=Save In Open MCT No items >> input[type="search"] | ||||
|     await page.locator('text=Save In Open MCT No items >> input[type="search"]').click(); | ||||
|  | ||||
|     // Fill text=Save In Open MCT No items >> input[type="search"] | ||||
|     await page.locator('text=Save In Open MCT No items >> input[type="search"]').fill('Unnamed Display Layout'); | ||||
|  | ||||
|     // Click text=OK Cancel | ||||
|     await page.locator('text=OK Cancel').click(); | ||||
|  | ||||
|     // Click text=OK | ||||
|     await page.click('text=OK'); | ||||
|  | ||||
|     // Take a snapshot of the newly created Display Layout object | ||||
|     await page.waitForTimeout(VISUAL_GRACE_PERIOD); | ||||
|     await percySnapshot(page, 'Default Sine Wave Generator'); | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| { | ||||
|   "name": "openmct", | ||||
|   "version": "2.0.1-SNAPSHOT", | ||||
|   "version": "2.0.1", | ||||
|   "description": "The Open MCT core platform", | ||||
|   "devDependencies": { | ||||
|     "@braintree/sanitize-url": "6.0.0", | ||||
|   | ||||
| @@ -269,7 +269,6 @@ define([ | ||||
|         this.install(this.plugins.ViewDatumAction()); | ||||
|         this.install(this.plugins.ViewLargeAction()); | ||||
|         this.install(this.plugins.ObjectInterceptors()); | ||||
|         this.install(this.plugins.NonEditableFolder()); | ||||
|         this.install(this.plugins.DeviceClassifier()); | ||||
|         this.install(this.plugins.UserIndicator()); | ||||
|     } | ||||
|   | ||||
| @@ -15,7 +15,8 @@ export default function (folderName, couchPlugin, searchFilter) { | ||||
|                     return Promise.resolve({ | ||||
|                         identifier, | ||||
|                         type: 'folder', | ||||
|                         name: folderName || "CouchDB Documents" | ||||
|                         name: folderName || "CouchDB Documents", | ||||
|                         location: 'ROOT' | ||||
|                     }); | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -85,7 +85,8 @@ describe('the plugin', function () { | ||||
|             expect(object).toEqual({ | ||||
|                 identifier, | ||||
|                 type: 'folder', | ||||
|                 name: "CouchDB Documents" | ||||
|                 name: 'CouchDB Documents', | ||||
|                 location: 'ROOT' | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -325,16 +325,7 @@ export default { | ||||
|             return item && (item.type === type); | ||||
|         }, | ||||
|         canPersistObject(item) { | ||||
|             // for now the only way to tell if an object can be persisted is if it is creatable. | ||||
|             let creatable = false; | ||||
|             if (item) { | ||||
|                 const type = this.openmct.types.get(item.type); | ||||
|                 if (type && type.definition) { | ||||
|                     creatable = (type.definition.creatable !== undefined && (type.definition.creatable === 'true' || type.definition.creatable === true)); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return creatable; | ||||
|             return this.openmct.objects.isPersistable(item.identifier); | ||||
|         }, | ||||
|         hasConditionalStyle(domainObject, layoutItem) { | ||||
|             const id = layoutItem ? layoutItem.id : undefined; | ||||
|   | ||||
| @@ -166,7 +166,7 @@ export default { | ||||
|     }, | ||||
|     computed: { | ||||
|         gridSize() { | ||||
|             return this.domainObject.configuration.layoutGrid; | ||||
|             return this.domainObject.configuration.layoutGrid.map(Number); | ||||
|         }, | ||||
|         layoutItems() { | ||||
|             return this.domainObject.configuration.items; | ||||
|   | ||||
| @@ -97,13 +97,16 @@ export default class DuplicateAction { | ||||
|  | ||||
|     validate(currentParent) { | ||||
|         return (data) => { | ||||
|             const parentCandidatePath = data.value; | ||||
|             const parentCandidate = parentCandidatePath[0]; | ||||
|             const parentCandidate = data.value[0]; | ||||
|  | ||||
|             let currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier); | ||||
|             let parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier); | ||||
|             let objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier); | ||||
|  | ||||
|             if (!this.openmct.objects.isPersistable(parentCandidate.identifier)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             if (!parentCandidateKeystring || !currentParentKeystring) { | ||||
|                 return false; | ||||
|             } | ||||
| @@ -122,13 +125,14 @@ export default class DuplicateAction { | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|         let parent = objectPath[1]; | ||||
|         let parentType = parent && this.openmct.types.get(parent.type); | ||||
|         let child = objectPath[0]; | ||||
|         let childType = child && this.openmct.types.get(child.type); | ||||
|         let locked = child.locked ? child.locked : parent && parent.locked; | ||||
|         const parent = objectPath[1]; | ||||
|         const parentType = parent && this.openmct.types.get(parent.type); | ||||
|         const child = objectPath[0]; | ||||
|         const childType = child && this.openmct.types.get(child.type); | ||||
|         const locked = child.locked ? child.locked : parent && parent.locked; | ||||
|         const isPersistable = this.openmct.objects.isPersistable(child.identifier); | ||||
|  | ||||
|         if (locked) { | ||||
|         if (locked || !isPersistable) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -52,7 +52,7 @@ export default class ExportAsJSONAction { | ||||
|     appliesTo(objectPath) { | ||||
|         let domainObject = objectPath[0]; | ||||
|  | ||||
|         return this._isCreatable(domainObject); | ||||
|         return this._isCreatableAndPersistable(domainObject); | ||||
|     } | ||||
|     /** | ||||
|      * | ||||
| @@ -80,10 +80,11 @@ export default class ExportAsJSONAction { | ||||
|      * @param {object} domainObject | ||||
|      * @returns {boolean} | ||||
|      */ | ||||
|     _isCreatable(domainObject) { | ||||
|     _isCreatableAndPersistable(domainObject) { | ||||
|         const type = this.openmct.types.get(domainObject.type); | ||||
|         const isPersistable = this.openmct.objects.isPersistable(domainObject.identifier); | ||||
|  | ||||
|         return type && type.definition.creatable; | ||||
|         return type && type.definition.creatable && isPersistable; | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
| @@ -170,7 +171,7 @@ export default class ExportAsJSONAction { | ||||
|                 .then((children) => { | ||||
|                     children.forEach((child, index) => { | ||||
|                         // Only export if object is creatable | ||||
|                         if (this._isCreatable(child)) { | ||||
|                         if (this._isCreatableAndPersistable(child)) { | ||||
|                             // Prevents infinite export of self-contained objs | ||||
|                             if (!Object.prototype.hasOwnProperty.call(this.tree, this._getId(child))) { | ||||
|                                 // If object is a link to something absent from | ||||
|   | ||||
| @@ -27,6 +27,10 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to folder', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -40,6 +44,10 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to telemetry.plot.overlay', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -53,6 +61,10 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to telemetry.plot.stacked', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -64,16 +76,24 @@ describe('Export as JSON plugin', () => { | ||||
|         expect(exportAsJSONAction.appliesTo([domainObject])).toEqual(true); | ||||
|     }); | ||||
|  | ||||
|     it('ExportAsJSONAction applies does not applies to non-creatable objects', () => { | ||||
|     it('ExportAsJSONAction does not applie to non-persistable objects', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
|             name: 'Non Editable Folder', | ||||
|             persisted: 1640115501237, | ||||
|             type: 'noneditable.folder' | ||||
|             type: 'folder' | ||||
|         }; | ||||
|  | ||||
|         spyOn(openmct.objects, 'getProvider').and.callFake(() => { | ||||
|             return { get: () => domainObject }; | ||||
|         }); | ||||
|  | ||||
|         expect(exportAsJSONAction.appliesTo([domainObject])).toEqual(false); | ||||
|     }); | ||||
|  | ||||
|   | ||||
| @@ -43,7 +43,7 @@ | ||||
|         <template v-for="(container, index) in containers"> | ||||
|             <drop-hint | ||||
|                 v-if="index === 0 && containers.length > 1" | ||||
|                 :key="index" | ||||
|                 :key="`hint-top-${container.id}`" | ||||
|                 class="c-fl-frame__drop-hint" | ||||
|                 :index="-1" | ||||
|                 :allow-drop="allowContainerDrop" | ||||
| @@ -51,7 +51,7 @@ | ||||
|             /> | ||||
|  | ||||
|             <container-component | ||||
|                 :key="container.id" | ||||
|                 :key="`component-${container.id}`" | ||||
|                 class="c-fl__container" | ||||
|                 :index="index" | ||||
|                 :container="container" | ||||
| @@ -66,7 +66,7 @@ | ||||
|  | ||||
|             <resize-handle | ||||
|                 v-if="index !== (containers.length - 1)" | ||||
|                 :key="index" | ||||
|                 :key="`handle-${container.id}`" | ||||
|                 :index="index" | ||||
|                 :orientation="rowsLayout ? 'vertical' : 'horizontal'" | ||||
|                 :is-editing="isEditing" | ||||
| @@ -77,7 +77,7 @@ | ||||
|  | ||||
|             <drop-hint | ||||
|                 v-if="containers.length > 1" | ||||
|                 :key="index" | ||||
|                 :key="`hint-bottom-${container.id}`" | ||||
|                 class="c-fl-frame__drop-hint" | ||||
|                 :index="index" | ||||
|                 :allow-drop="allowContainerDrop" | ||||
|   | ||||
| @@ -101,7 +101,10 @@ export default class CreateWizard { | ||||
|         // Ensure there is always a 'save in' section | ||||
|         if (includeLocation) { | ||||
|             function validateLocation(data) { | ||||
|                 return self.openmct.composition.checkPolicy(data.value[0], domainObject); | ||||
|                 const policyCheck = self.openmct.composition.checkPolicy(data.value[0], domainObject); | ||||
|                 const parentIsPersistable = self.openmct.objects.isPersistable(data.value[0].identifier); | ||||
|  | ||||
|                 return policyCheck && parentIsPersistable; | ||||
|             } | ||||
|  | ||||
|             sections.push({ | ||||
|   | ||||
| @@ -33,10 +33,7 @@ export default class LinkAction { | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|         let domainObject = objectPath[0]; | ||||
|         let type = domainObject && this.openmct.types.get(domainObject.type); | ||||
|  | ||||
|         return type && type.definition.creatable; | ||||
|         return true; // link away! | ||||
|     } | ||||
|  | ||||
|     invoke(objectPath) { | ||||
| @@ -77,6 +74,7 @@ export default class LinkAction { | ||||
|                         { | ||||
|                             name: "location", | ||||
|                             control: "locator", | ||||
|                             parent: parentDomainObject, | ||||
|                             required: true, | ||||
|                             validate: this.validate(parentDomainObject), | ||||
|                             key: 'location' | ||||
| @@ -92,11 +90,26 @@ export default class LinkAction { | ||||
|  | ||||
|     validate(currentParent) { | ||||
|         return (data) => { | ||||
|  | ||||
|             // default current parent to ROOT, if it's undefined, then it's a root level item | ||||
|             if (currentParent === undefined) { | ||||
|                 currentParent = { | ||||
|                     identifier: { | ||||
|                         key: 'ROOT', | ||||
|                         namespace: '' | ||||
|                     } | ||||
|                 }; | ||||
|             } | ||||
|  | ||||
|             const parentCandidate = data.value[0]; | ||||
|             const currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier); | ||||
|             const parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier); | ||||
|             const objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier); | ||||
|  | ||||
|             if (!this.openmct.objects.isPersistable(parentCandidate.identifier)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             if (!parentCandidateKeystring || !currentParentKeystring) { | ||||
|                 return false; | ||||
|             } | ||||
|   | ||||
| @@ -126,6 +126,7 @@ export default class MoveAction { | ||||
|                         { | ||||
|                             name: "Location", | ||||
|                             control: "locator", | ||||
|                             parent: parentDomainObject, | ||||
|                             required: true, | ||||
|                             validate: this.validate(parentDomainObject), | ||||
|                             key: 'location' | ||||
| @@ -144,6 +145,10 @@ export default class MoveAction { | ||||
|             const parentCandidatePath = data.value; | ||||
|             const parentCandidate = parentCandidatePath[0]; | ||||
|  | ||||
|             if (!this.openmct.objects.isPersistable(parentCandidate.identifier)) { | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             let currentParentKeystring = this.openmct.objects.makeKeyString(currentParent.identifier); | ||||
|             let parentCandidateKeystring = this.openmct.objects.makeKeyString(parentCandidate.identifier); | ||||
|             let objectKeystring = this.openmct.objects.makeKeyString(this.object.identifier); | ||||
| @@ -174,8 +179,9 @@ export default class MoveAction { | ||||
|         let parentType = parent && this.openmct.types.get(parent.type); | ||||
|         let child = objectPath[0]; | ||||
|         let childType = child && this.openmct.types.get(child.type); | ||||
|         let isPersistable = this.openmct.objects.isPersistable(child.identifier); | ||||
|  | ||||
|         if (child.locked || (parent && parent.locked)) { | ||||
|         if (child.locked || (parent && parent.locked) || !isPersistable) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -1,33 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2022, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| export default function () { | ||||
|     return function (openmct) { | ||||
|         openmct.types.addType("noneditable.folder", { | ||||
|             name: "Non-Editable Folder", | ||||
|             key: "noneditable.folder", | ||||
|             description: "Create folders to organize other objects or links to objects without the ability to edit it's properties.", | ||||
|             cssClass: "icon-folder", | ||||
|             creatable: false | ||||
|         }); | ||||
|     }; | ||||
| } | ||||
| @@ -1,50 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2022, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| import { | ||||
|     createOpenMct, | ||||
|     resetApplicationState | ||||
| } from 'utils/testing'; | ||||
|  | ||||
| describe("the plugin", () => { | ||||
|     const NON_EDITABLE_FOLDER_KEY = 'noneditable.folder'; | ||||
|     let openmct; | ||||
|  | ||||
|     beforeEach((done) => { | ||||
|         openmct = createOpenMct(); | ||||
|         openmct.install(openmct.plugins.NonEditableFolder()); | ||||
|  | ||||
|         openmct.on('start', done); | ||||
|         openmct.startHeadless(); | ||||
|     }); | ||||
|  | ||||
|     afterEach(() => { | ||||
|         return resetApplicationState(openmct); | ||||
|     }); | ||||
|  | ||||
|     it('adds the new non-editable folder type', () => { | ||||
|         const type = openmct.types.get(NON_EDITABLE_FOLDER_KEY); | ||||
|  | ||||
|         expect(type).toBeDefined(); | ||||
|         expect(type.definition.creatable).toBeFalse(); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
| @@ -61,7 +61,6 @@ define([ | ||||
|     './URLTimeSettingsSynchronizer/plugin', | ||||
|     './notificationIndicator/plugin', | ||||
|     './newFolderAction/plugin', | ||||
|     './nonEditableFolder/plugin', | ||||
|     './persistence/couch/plugin', | ||||
|     './defaultRootName/plugin', | ||||
|     './plan/plugin', | ||||
| @@ -119,7 +118,6 @@ define([ | ||||
|     URLTimeSettingsSynchronizer, | ||||
|     NotificationIndicator, | ||||
|     NewFolderAction, | ||||
|     NonEditableFolder, | ||||
|     CouchDBPlugin, | ||||
|     DefaultRootName, | ||||
|     PlanLayout, | ||||
| @@ -197,7 +195,6 @@ define([ | ||||
|     plugins.URLTimeSettingsSynchronizer = URLTimeSettingsSynchronizer.default; | ||||
|     plugins.NotificationIndicator = NotificationIndicator.default; | ||||
|     plugins.NewFolderAction = NewFolderAction.default; | ||||
|     plugins.NonEditableFolder = NonEditableFolder.default; | ||||
|     plugins.ISOTimeFormat = ISOTimeFormat.default; | ||||
|     plugins.DefaultRootName = DefaultRootName.default; | ||||
|     plugins.PlanLayout = PlanLayout.default; | ||||
|   | ||||
| @@ -92,20 +92,35 @@ export default class RemoveAction { | ||||
|             this.openmct.editor.save(); | ||||
|         } | ||||
|  | ||||
|         const parentKeyString = this.openmct.objects.makeKeyString(parent.identifier); | ||||
|         const isAlias = parentKeyString !== child.location; | ||||
|  | ||||
|         if (!isAlias) { | ||||
|         if (!this.isAlias(child, parent)) { | ||||
|             this.openmct.objects.mutate(child, 'location', null); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     isAlias(child, parent) { | ||||
|         if (parent === undefined) { | ||||
|             // then it's a root item, not an alias | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         const parentKeyString = this.openmct.objects.makeKeyString(parent.identifier); | ||||
|         const childLocation = child.location; | ||||
|  | ||||
|         return childLocation !== parentKeyString; | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|         let parent = objectPath[1]; | ||||
|         let parentType = parent && this.openmct.types.get(parent.type); | ||||
|         let child = objectPath[0]; | ||||
|         let locked = child.locked ? child.locked : parent && parent.locked; | ||||
|         let isEditing = this.openmct.editor.isEditing(); | ||||
|         const parent = objectPath[1]; | ||||
|         const parentType = parent && this.openmct.types.get(parent.type); | ||||
|         const child = objectPath[0]; | ||||
|         const locked = child.locked ? child.locked : parent && parent.locked; | ||||
|         const isEditing = this.openmct.editor.isEditing(); | ||||
|         const isPersistable = this.openmct.objects.isPersistable(child.identifier); | ||||
|         const isAlias = this.isAlias(child, parent); | ||||
|  | ||||
|         if (locked || (!isPersistable && !isAlias)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (isEditing) { | ||||
|             let currentItemInView = this.openmct.router.path[0]; | ||||
| @@ -116,10 +131,6 @@ export default class RemoveAction { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (locked) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return parentType | ||||
|             && parentType.definition.creatable | ||||
|             && Array.isArray(parent.composition); | ||||
|   | ||||
| @@ -31,9 +31,11 @@ | ||||
| > | ||||
|     <div class="c-conductor__time-bounds"> | ||||
|         <conductor-inputs-fixed v-if="isFixed" | ||||
|                                 :input-bounds="viewBounds" | ||||
|                                 @updated="saveFixedOffsets" | ||||
|         /> | ||||
|         <conductor-inputs-realtime v-else | ||||
|                                    :input-bounds="viewBounds" | ||||
|                                    @updated="saveClockOffsets" | ||||
|         /> | ||||
|         <ConductorModeIcon class="c-conductor__mode-icon" /> | ||||
|   | ||||
| @@ -71,6 +71,12 @@ export default { | ||||
|             default() { | ||||
|                 return undefined; | ||||
|             } | ||||
|         }, | ||||
|         inputBounds: { | ||||
|             type: Object, | ||||
|             default() { | ||||
|                 return undefined; | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     data() { | ||||
| @@ -98,6 +104,12 @@ export default { | ||||
|     watch: { | ||||
|         keyString() { | ||||
|             this.setTimeContext(); | ||||
|         }, | ||||
|         inputBounds: { | ||||
|             handler(newBounds) { | ||||
|                 this.handleNewBounds(newBounds); | ||||
|             }, | ||||
|             deep: true | ||||
|         } | ||||
|     }, | ||||
|     mounted() { | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
|             ref="startOffset" | ||||
|             class="c-button c-conductor__delta-button" | ||||
|             title="Set the time offset after now" | ||||
|             @click.prevent="showTimePopupStart" | ||||
|             @click.prevent.stop="showTimePopupStart" | ||||
|         > | ||||
|             {{ offsets.start }} | ||||
|         </button> | ||||
| @@ -60,7 +60,7 @@ | ||||
|             ref="endOffset" | ||||
|             class="c-button c-conductor__delta-button" | ||||
|             title="Set the time offset preceding now" | ||||
|             @click.prevent="showTimePopupEnd" | ||||
|             @click.prevent.stop="showTimePopupEnd" | ||||
|         > | ||||
|             {{ offsets.end }} | ||||
|         </button> | ||||
| @@ -86,6 +86,12 @@ export default { | ||||
|             default() { | ||||
|                 return undefined; | ||||
|             } | ||||
|         }, | ||||
|         inputBounds: { | ||||
|             type: Object, | ||||
|             default() { | ||||
|                 return undefined; | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     data() { | ||||
| @@ -118,6 +124,12 @@ export default { | ||||
|     watch: { | ||||
|         keyString() { | ||||
|             this.setTimeContext(); | ||||
|         }, | ||||
|         inputBounds: { | ||||
|             handler(newBounds) { | ||||
|                 this.handleNewBounds(newBounds); | ||||
|             }, | ||||
|             deep: true | ||||
|         } | ||||
|     }, | ||||
|     mounted() { | ||||
|   | ||||
| @@ -122,6 +122,9 @@ | ||||
|         flex: 1 1 auto; | ||||
|         height: 0; // Chrome 73 overflow bug fix | ||||
|         overflow: auto; | ||||
|         //To accommodate independent time conductor controls | ||||
|         display: flex; | ||||
|         flex-direction: column; | ||||
|  | ||||
|         .u-fills-container { | ||||
|             // Expand component types that fill a container | ||||
|   | ||||
| @@ -258,10 +258,12 @@ export default { | ||||
|         if (!this.isSelectorTree) { | ||||
|             await this.syncTreeOpenItems(); | ||||
|         } else { | ||||
|             const objectPath = await this.openmct.objects.getOriginalPath(this.initialSelection.identifier); | ||||
|             const navigationPath = this.buildNavigationPath(objectPath); | ||||
|             if (this.initialSelection.identifier) { | ||||
|                 const objectPath = await this.openmct.objects.getOriginalPath(this.initialSelection.identifier); | ||||
|                 const navigationPath = this.buildNavigationPath(objectPath); | ||||
|  | ||||
|             this.openAndScrollTo(navigationPath); | ||||
|                 this.openAndScrollTo(navigationPath); | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|     created() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user