Compare commits
	
		
			8 Commits
		
	
	
		
			persistabi
			...
			bugfix/iss
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 064e517031 | ||
|   | 7096710b1f | ||
|   | ecfbabcfe3 | ||
|   | a76b843fde | ||
|   | 7f0367b838 | ||
|   | 04c3728eff | ||
|   | afa89ae6b5 | ||
|   | 58844799be | 
							
								
								
									
										2
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/codeql-analysis.yml
									
									
									
									
										vendored
									
									
								
							| @@ -28,7 +28,7 @@ jobs: | ||||
|  | ||||
|     steps: | ||||
|     - name: Checkout repository | ||||
|       uses: actions/checkout@v3 | ||||
|       uses: actions/checkout@v2 | ||||
|  | ||||
|     # Initializes the CodeQL tools for scanning. | ||||
|     - name: Initialize CodeQL | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/e2e-pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/e2e-pr.yml
									
									
									
									
										vendored
									
									
								
							| @@ -26,8 +26,8 @@ jobs: | ||||
|               repo: "openmct", | ||||
|               body: 'Started e2e Run. Follow along: https://github.com/nasa/openmct/actions/runs/' + context.runId | ||||
|             }) | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/setup-node@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '16' | ||||
|       - run: npx playwright install-deps | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/e2e-visual.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/e2e-visual.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,8 +13,8 @@ jobs: | ||||
|     if: ${{ github.event.label.name == 'pr:visual' }} || ${{ github.event.workflow_dispatch }} || ${{ github.event.schedule }} | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/setup-node@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '16' | ||||
|       - run: npx playwright install-deps | ||||
|   | ||||
							
								
								
									
										4
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/e2e.yml
									
									
									
									
										vendored
									
									
								
							| @@ -10,10 +10,10 @@ jobs: | ||||
|   e2e: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|         with: | ||||
|           ref: ${{ github.event.inputs.version }} | ||||
|       - uses: actions/setup-node@v3 | ||||
|       - uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '16' | ||||
|       - run: npm install | ||||
|   | ||||
							
								
								
									
										16
									
								
								.github/workflows/lighthouse.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/lighthouse.yml
									
									
									
									
										vendored
									
									
								
							| @@ -17,11 +17,11 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout Master for Baseline | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|           ref: master #explicitly checkout master for baseline | ||||
|       - name: Install Node 14 | ||||
|         uses: actions/setup-node@v3 | ||||
|         uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '14' | ||||
|       - name: Cache node modules | ||||
| @@ -38,11 +38,11 @@ jobs: | ||||
|       - name: Run lhci against master to generate baseline and ignore exit codes | ||||
|         run: lhci autorun || true | ||||
|       - name: Perform clean checkout of PR | ||||
|         uses: actions/checkout@v3 | ||||
|         uses: actions/checkout@v2 | ||||
|         with: | ||||
|           clean: true | ||||
|       - name: Install Node version which is compatible with PR | ||||
|         uses: actions/setup-node@v3 | ||||
|         uses: actions/setup-node@v2 | ||||
|       - name: npm install with lighthouse cli  | ||||
|         run: npm install && npm install -g @lhci/cli | ||||
|       - name: Run lhci with PR | ||||
| @@ -53,9 +53,9 @@ jobs: | ||||
|     if: ${{ github.event.schedule }} | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - name: Install Node 14 | ||||
|         uses: actions/setup-node@v3 | ||||
|         uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '14' | ||||
|       - name: Cache node modules | ||||
| @@ -77,11 +77,11 @@ jobs: | ||||
|     if: ${{ github.event.workflow_dispatch }} | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|         with: | ||||
|           ref: ${{ github.event.inputs.version }} | ||||
|       - name: Install Node 14 | ||||
|         uses: actions/setup-node@v3 | ||||
|         uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: '14' | ||||
|       - name: Cache node modules | ||||
|   | ||||
							
								
								
									
										8
									
								
								.github/workflows/npm-prerelease.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/npm-prerelease.yml
									
									
									
									
										vendored
									
									
								
							| @@ -11,8 +11,8 @@ jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/setup-node@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: 16 | ||||
|       - run: npm install | ||||
| @@ -22,8 +22,8 @@ jobs: | ||||
|     needs: build | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/setup-node@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: 16 | ||||
|           registry-url: https://registry.npmjs.org/ | ||||
|   | ||||
							
								
								
									
										6
									
								
								.github/workflows/pr-platform.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/pr-platform.yml
									
									
									
									
										vendored
									
									
								
							| @@ -23,12 +23,12 @@ jobs: | ||||
|           - x64 | ||||
|     name: Node ${{ matrix.node_version }} - ${{ matrix.architecture }} on ${{ matrix.os }} | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|       - uses: actions/checkout@v2 | ||||
|       - name: Setup node | ||||
|         uses: actions/setup-node@v3 | ||||
|         uses: actions/setup-node@v2 | ||||
|         with: | ||||
|           node-version: ${{ matrix.node_version }} | ||||
|           architecture: ${{ matrix.architecture }} | ||||
|       - run: npm install | ||||
|       - run: npm test | ||||
|       - run: npm run lint -- --quiet | ||||
|       - run: npm run lint | ||||
|   | ||||
| @@ -26,8 +26,8 @@ This test suite is dedicated to tests which verify the basic operations surround | ||||
|  | ||||
| const { test, expect } = require('@playwright/test'); | ||||
|  | ||||
| test.describe('Condition Set Operations', () => { | ||||
|     test('Create new button `condition set` creates new condition object', async ({ page }) => { | ||||
| test.describe('condition set', () => { | ||||
|     test('create new button `condition set` creates new condition object', async ({ page }) => { | ||||
|         //Go to baseURL | ||||
|         await page.goto('/', { waitUntil: 'networkidle' }); | ||||
|  | ||||
| @@ -45,21 +45,4 @@ test.describe('Condition Set Operations', () => { | ||||
|  | ||||
|         await expect(page.locator('.l-browse-bar__object-name')).toContainText('Unnamed Condition Set'); | ||||
|     }); | ||||
|     test.fixme('condition set object properties exist', async ({ page }) => { | ||||
|         //Go to object created in step one | ||||
|         //Verify the Condition Set properties persist on Save | ||||
|         //Verify the Condition Set properties persist on page.reload() | ||||
|     }); | ||||
|     test.fixme('condition set object can be modified', async ({ page }) => { | ||||
|         //Go to object created in step one | ||||
|         //Update the Condition Set properties | ||||
|         //Verify the Condition Set properties persist on Save | ||||
|         //Verify the Condition Set properties persist on page.reload() | ||||
|     }); | ||||
|     test.fixme('condition set object can be deleted', async ({ page }) => { | ||||
|         //Go to object created in step one | ||||
|         //Verify that Condition Set object can be deleted | ||||
|         //Verify the Condition Set object does not exist in Tree | ||||
|         //Verify the Condition Set object does not exist with direct navigation to object's URL | ||||
|     }); | ||||
| }); | ||||
|   | ||||
| @@ -195,6 +195,7 @@ | ||||
|         )); | ||||
|         openmct.install(openmct.plugins.Clock({ enableClockIndicator: true })); | ||||
|         openmct.install(openmct.plugins.Timer()); | ||||
|         openmct.install(openmct.plugins.StaticRootPlugin({ namespace: 'something', exportUrl: './dist/static-root.json' })); | ||||
|         openmct.start(); | ||||
|     </script> | ||||
| </html> | ||||
|   | ||||
| @@ -3,10 +3,10 @@ | ||||
|   "version": "2.0.1-SNAPSHOT", | ||||
|   "description": "The Open MCT core platform", | ||||
|   "devDependencies": { | ||||
|     "@braintree/sanitize-url": "6.0.0", | ||||
|     "@braintree/sanitize-url": "5.0.2", | ||||
|     "@percy/cli": "1.0.0-beta.75", | ||||
|     "@percy/playwright": "1.0.1", | ||||
|     "@playwright/test": "1.19.2", | ||||
|     "@playwright/test": "1.19.1", | ||||
|     "allure-playwright": "2.0.0-beta.15", | ||||
|     "babel-eslint": "10.1.0", | ||||
|     "comma-separated-values": "3.6.4", | ||||
|   | ||||
| @@ -269,6 +269,7 @@ 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()); | ||||
|     } | ||||
|   | ||||
| @@ -325,7 +325,16 @@ export default { | ||||
|             return item && (item.type === type); | ||||
|         }, | ||||
|         canPersistObject(item) { | ||||
|             return this.openmct.objects.isPersistable(item.identifier); | ||||
|             // 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; | ||||
|         }, | ||||
|         hasConditionalStyle(domainObject, layoutItem) { | ||||
|             const id = layoutItem ? layoutItem.id : undefined; | ||||
|   | ||||
| @@ -97,16 +97,13 @@ export default class DuplicateAction { | ||||
|  | ||||
|     validate(currentParent) { | ||||
|         return (data) => { | ||||
|             const parentCandidate = data.value[0]; | ||||
|             const parentCandidatePath = data.value; | ||||
|             const parentCandidate = parentCandidatePath[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; | ||||
|             } | ||||
| @@ -125,14 +122,13 @@ export default class DuplicateAction { | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|         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); | ||||
|         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; | ||||
|  | ||||
|         if (locked || !isPersistable) { | ||||
|         if (locked) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -52,7 +52,7 @@ export default class ExportAsJSONAction { | ||||
|     appliesTo(objectPath) { | ||||
|         let domainObject = objectPath[0]; | ||||
|  | ||||
|         return this._isCreatableAndPersistable(domainObject); | ||||
|         return this._isCreatable(domainObject); | ||||
|     } | ||||
|     /** | ||||
|      * | ||||
| @@ -80,11 +80,10 @@ export default class ExportAsJSONAction { | ||||
|      * @param {object} domainObject | ||||
|      * @returns {boolean} | ||||
|      */ | ||||
|     _isCreatableAndPersistable(domainObject) { | ||||
|     _isCreatable(domainObject) { | ||||
|         const type = this.openmct.types.get(domainObject.type); | ||||
|         const isPersistable = this.openmct.objects.isPersistable(domainObject.identifier); | ||||
|  | ||||
|         return type && type.definition.creatable && isPersistable; | ||||
|         return type && type.definition.creatable; | ||||
|     } | ||||
|     /** | ||||
|      * @private | ||||
| @@ -171,7 +170,7 @@ export default class ExportAsJSONAction { | ||||
|                 .then((children) => { | ||||
|                     children.forEach((child, index) => { | ||||
|                         // Only export if object is creatable | ||||
|                         if (this._isCreatableAndPersistable(child)) { | ||||
|                         if (this._isCreatable(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,10 +27,6 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to folder', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -44,10 +40,6 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to telemetry.plot.overlay', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -61,10 +53,6 @@ describe('Export as JSON plugin', () => { | ||||
|  | ||||
|     it('ExportAsJSONAction applies to telemetry.plot.stacked', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
| @@ -76,24 +64,16 @@ describe('Export as JSON plugin', () => { | ||||
|         expect(exportAsJSONAction.appliesTo([domainObject])).toEqual(true); | ||||
|     }); | ||||
|  | ||||
|     it('ExportAsJSONAction does not applie to non-persistable objects', () => { | ||||
|     it('ExportAsJSONAction applies does not applies to non-creatable objects', () => { | ||||
|         domainObject = { | ||||
|             identifier: { | ||||
|                 key: 'export-testing', | ||||
|                 namespace: '' | ||||
|             }, | ||||
|             composition: [], | ||||
|             location: 'mine', | ||||
|             modified: 1640115501237, | ||||
|             name: 'Non Editable Folder', | ||||
|             persisted: 1640115501237, | ||||
|             type: 'folder' | ||||
|             type: 'noneditable.folder' | ||||
|         }; | ||||
|  | ||||
|         spyOn(openmct.objects, 'getProvider').and.callFake(() => { | ||||
|             return { get: () => domainObject }; | ||||
|         }); | ||||
|  | ||||
|         expect(exportAsJSONAction.appliesTo([domainObject])).toEqual(false); | ||||
|     }); | ||||
|  | ||||
|   | ||||
| @@ -101,10 +101,7 @@ export default class CreateWizard { | ||||
|         // Ensure there is always a 'save in' section | ||||
|         if (includeLocation) { | ||||
|             function validateLocation(data) { | ||||
|                 const policyCheck = self.openmct.composition.checkPolicy(data.value[0], domainObject); | ||||
|                 const parentIsPersistable = self.openmct.objects.isPersistable(data.value[0].identifier); | ||||
|  | ||||
|                 return policyCheck && parentIsPersistable; | ||||
|                 return self.openmct.composition.checkPolicy(data.value[0], domainObject); | ||||
|             } | ||||
|  | ||||
|             sections.push({ | ||||
|   | ||||
| @@ -33,7 +33,10 @@ export default class LinkAction { | ||||
|     } | ||||
|  | ||||
|     appliesTo(objectPath) { | ||||
|         return true; // link away! | ||||
|         let domainObject = objectPath[0]; | ||||
|         let type = domainObject && this.openmct.types.get(domainObject.type); | ||||
|  | ||||
|         return type && type.definition.creatable; | ||||
|     } | ||||
|  | ||||
|     invoke(objectPath) { | ||||
| @@ -74,7 +77,6 @@ export default class LinkAction { | ||||
|                         { | ||||
|                             name: "location", | ||||
|                             control: "locator", | ||||
|                             parent: parentDomainObject, | ||||
|                             required: true, | ||||
|                             validate: this.validate(parentDomainObject), | ||||
|                             key: 'location' | ||||
| @@ -95,10 +97,6 @@ export default class LinkAction { | ||||
|             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,7 +126,6 @@ export default class MoveAction { | ||||
|                         { | ||||
|                             name: "Location", | ||||
|                             control: "locator", | ||||
|                             parent: parentDomainObject, | ||||
|                             required: true, | ||||
|                             validate: this.validate(parentDomainObject), | ||||
|                             key: 'location' | ||||
| @@ -145,10 +144,6 @@ 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); | ||||
| @@ -179,9 +174,8 @@ 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) || !isPersistable) { | ||||
|         if (child.locked || (parent && parent.locked)) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|   | ||||
							
								
								
									
										33
									
								
								src/plugins/nonEditableFolder/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/plugins/nonEditableFolder/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| /***************************************************************************** | ||||
|  * 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 | ||||
|         }); | ||||
|     }; | ||||
| } | ||||
							
								
								
									
										50
									
								
								src/plugins/nonEditableFolder/pluginSpec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/plugins/nonEditableFolder/pluginSpec.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| /***************************************************************************** | ||||
|  * 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(); | ||||
|     }); | ||||
|  | ||||
| }); | ||||
| @@ -21,7 +21,6 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| export function getValidatedPlan(domainObject) { | ||||
|     let sourceMap = domainObject.sourceMap; | ||||
|     let body = domainObject.selectFile.body; | ||||
|     let json = {}; | ||||
|     if (typeof body === 'string') { | ||||
| @@ -34,33 +33,5 @@ export function getValidatedPlan(domainObject) { | ||||
|         json = body; | ||||
|     } | ||||
|  | ||||
|     if (sourceMap !== undefined && sourceMap.activities !== undefined && sourceMap.groupId !== undefined) { | ||||
|         let mappedJson = {}; | ||||
|         json[sourceMap.activities].forEach((activity) => { | ||||
|             if (activity[sourceMap.groupId]) { | ||||
|                 const groupIdKey = activity[sourceMap.groupId]; | ||||
|                 let groupActivity = { | ||||
|                     ...activity | ||||
|                 }; | ||||
|  | ||||
|                 if (sourceMap.start) { | ||||
|                     groupActivity.start = activity[sourceMap.start]; | ||||
|                 } | ||||
|  | ||||
|                 if (sourceMap.end) { | ||||
|                     groupActivity.end = activity[sourceMap.end]; | ||||
|                 } | ||||
|  | ||||
|                 if (!mappedJson[groupIdKey]) { | ||||
|                     mappedJson[groupIdKey] = []; | ||||
|                 } | ||||
|  | ||||
|                 mappedJson[groupIdKey].push(groupActivity); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         return mappedJson; | ||||
|     } else { | ||||
|         return json; | ||||
|     } | ||||
|     return json; | ||||
| } | ||||
|   | ||||
| @@ -61,6 +61,7 @@ define([ | ||||
|     './URLTimeSettingsSynchronizer/plugin', | ||||
|     './notificationIndicator/plugin', | ||||
|     './newFolderAction/plugin', | ||||
|     './nonEditableFolder/plugin', | ||||
|     './persistence/couch/plugin', | ||||
|     './defaultRootName/plugin', | ||||
|     './plan/plugin', | ||||
| @@ -118,6 +119,7 @@ define([ | ||||
|     URLTimeSettingsSynchronizer, | ||||
|     NotificationIndicator, | ||||
|     NewFolderAction, | ||||
|     NonEditableFolder, | ||||
|     CouchDBPlugin, | ||||
|     DefaultRootName, | ||||
|     PlanLayout, | ||||
| @@ -195,6 +197,7 @@ 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; | ||||
|   | ||||
| @@ -106,11 +106,6 @@ export default class RemoveAction { | ||||
|         let child = objectPath[0]; | ||||
|         let locked = child.locked ? child.locked : parent && parent.locked; | ||||
|         let isEditing = this.openmct.editor.isEditing(); | ||||
|         let isPersistable = this.openmct.objects.isPersistable(child.identifier); | ||||
|  | ||||
|         if (locked || !isPersistable) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         if (isEditing) { | ||||
|             let currentItemInView = this.openmct.router.path[0]; | ||||
| @@ -121,6 +116,10 @@ export default class RemoveAction { | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (locked) { | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         return parentType | ||||
|             && parentType.definition.creatable | ||||
|             && Array.isArray(parent.composition); | ||||
|   | ||||
| @@ -258,12 +258,10 @@ export default { | ||||
|         if (!this.isSelectorTree) { | ||||
|             await this.syncTreeOpenItems(); | ||||
|         } else { | ||||
|             if (this.initialSelection.identifier) { | ||||
|                 const objectPath = await this.openmct.objects.getOriginalPath(this.initialSelection.identifier); | ||||
|                 const navigationPath = this.buildNavigationPath(objectPath); | ||||
|             const objectPath = await this.openmct.objects.getOriginalPath(this.initialSelection.identifier); | ||||
|             const navigationPath = this.buildNavigationPath(objectPath); | ||||
|  | ||||
|                 this.openAndScrollTo(navigationPath); | ||||
|             } | ||||
|             this.openAndScrollTo(navigationPath); | ||||
|         } | ||||
|     }, | ||||
|     created() { | ||||
|   | ||||
							
								
								
									
										1
									
								
								static-root.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								static-root.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| {"openmct":{"a2de0f92-e1a9-4ab0-b815-8226eb016b33":{"identifier":{"key":"a2de0f92-e1a9-4ab0-b815-8226eb016b33","namespace":""},"name":"Parent Folder","type":"folder","composition":[{"key":"9cdda73d-9b0c-4b6d-8405-f90c33844e54","namespace":""},{"key":"d0ef5482-8bda-4082-b2e2-73807320d1d9","namespace":""},{"key":"97891e2c-6000-464f-a65d-e928fa0d172d","namespace":""}],"modified":1645824127466,"location":"mine","persisted":1645824127468},"9cdda73d-9b0c-4b6d-8405-f90c33844e54":{"identifier":{"key":"9cdda73d-9b0c-4b6d-8405-f90c33844e54","namespace":""},"name":"Child Folder","type":"folder","composition":[{"key":"aa6e8428-fe16-4033-9b04-8c63d559fe05","namespace":""},{"key":"f473b125-3aa3-419e-8fd9-004e08d42ba3","namespace":""}],"modified":1645824073376,"location":"a2de0f92-e1a9-4ab0-b815-8226eb016b33","persisted":1645824073378},"d0ef5482-8bda-4082-b2e2-73807320d1d9":{"identifier":{"key":"d0ef5482-8bda-4082-b2e2-73807320d1d9","namespace":""},"name":"Sibling Child Folder","type":"folder","composition":[{"key":"b9d53ee9-d5f0-404e-90c1-b0e4b30c3d54","namespace":""}],"modified":1645824073375,"location":"a2de0f92-e1a9-4ab0-b815-8226eb016b33","persisted":1645824073375},"97891e2c-6000-464f-a65d-e928fa0d172d":{"identifier":{"key":"97891e2c-6000-464f-a65d-e928fa0d172d","namespace":""},"name":"A Clock","type":"clock","configuration":{"baseFormat":"YYYY/MM/DD hh:mm:ss","use24":"clock12","timezone":"UTC"},"modified":1645824127465,"location":"a2de0f92-e1a9-4ab0-b815-8226eb016b33","persisted":1645824127465},"aa6e8428-fe16-4033-9b04-8c63d559fe05":{"identifier":{"key":"aa6e8428-fe16-4033-9b04-8c63d559fe05","namespace":""},"name":"Grandchild Folder","type":"folder","composition":[{"key":"f8f9dd1f-50fe-4bed-b0e4-dd85ce6d3498","namespace":""}],"modified":1645824155758,"location":"9cdda73d-9b0c-4b6d-8405-f90c33844e54","persisted":1645824155760},"f473b125-3aa3-419e-8fd9-004e08d42ba3":{"identifier":{"key":"f473b125-3aa3-419e-8fd9-004e08d42ba3","namespace":""},"name":"Secret Web Page","type":"webPage","url":"https://www.youtube.com/embed/dQw4w9WgXcQ","modified":1645823979349,"location":"9cdda73d-9b0c-4b6d-8405-f90c33844e54","persisted":1645823979349},"b9d53ee9-d5f0-404e-90c1-b0e4b30c3d54":{"identifier":{"key":"b9d53ee9-d5f0-404e-90c1-b0e4b30c3d54","namespace":""},"name":"Linky","type":"hyperlink","displayFormat":"link","linkTarget":"_self","url":"https://www.nasa.gov/viper/","displayText":"Viper Info","modified":1645824073374,"location":"d0ef5482-8bda-4082-b2e2-73807320d1d9","persisted":1645824073374},"f8f9dd1f-50fe-4bed-b0e4-dd85ce6d3498":{"identifier":{"key":"f8f9dd1f-50fe-4bed-b0e4-dd85ce6d3498","namespace":""},"name":"Display Layout","type":"layout","composition":[{"key":"f473b125-3aa3-419e-8fd9-004e08d42ba3","namespace":""},{"key":"b9d53ee9-d5f0-404e-90c1-b0e4b30c3d54","namespace":""},{"key":"97891e2c-6000-464f-a65d-e928fa0d172d","namespace":""}],"configuration":{"items":[{"width":58,"height":30,"x":1,"y":3,"identifier":{"key":"f473b125-3aa3-419e-8fd9-004e08d42ba3","namespace":""},"hasFrame":true,"fontSize":"default","font":"default","type":"subobject-view","id":"f7b49d10-d606-467f-bc08-5d660b8ae693"},{"width":11,"height":2,"x":60,"y":3,"identifier":{"key":"b9d53ee9-d5f0-404e-90c1-b0e4b30c3d54","namespace":""},"hasFrame":false,"fontSize":"default","font":"default","type":"subobject-view","id":"483b5762-455f-485e-a17d-24699dbcbe06"},{"width":31,"height":6,"x":60,"y":6,"identifier":{"key":"97891e2c-6000-464f-a65d-e928fa0d172d","namespace":""},"hasFrame":true,"fontSize":"default","font":"default","type":"subobject-view","id":"53026423-72c4-4b5f-9290-9c7abbd1bec7"}],"layoutGrid":[10,10]},"modified":1645824197324,"location":"aa6e8428-fe16-4033-9b04-8c63d559fe05","persisted":1645824201302}},"rootId":"a2de0f92-e1a9-4ab0-b815-8226eb016b33"} | ||||
| @@ -1,5 +1,6 @@ | ||||
| const { merge } = require('webpack-merge'); | ||||
| const common = require('./webpack.common'); | ||||
| const CopyWebpackPlugin = require('copy-webpack-plugin'); | ||||
|  | ||||
| const path = require('path'); | ||||
| const webpack = require('webpack'); | ||||
| @@ -14,6 +15,14 @@ module.exports = merge(common, { | ||||
|     plugins: [ | ||||
|         new webpack.DefinePlugin({ | ||||
|             __OPENMCT_ROOT_RELATIVE__: '"dist/"' | ||||
|         }), | ||||
|         new CopyWebpackPlugin({ | ||||
|             patterns: [ | ||||
|                 { | ||||
|                     from: './static-root.json', | ||||
|                     to: '.' | ||||
|                 } | ||||
|             ] | ||||
|         }) | ||||
|     ], | ||||
|     devtool: 'eval-source-map' | ||||
|   | ||||
		Reference in New Issue
	
	Block a user