diff --git a/index.html b/index.html index 3a69c14d0b..7996c72a5c 100644 --- a/index.html +++ b/index.html @@ -88,6 +88,7 @@ openmct.install(openmct.plugins.ExampleImagery()); openmct.install(openmct.plugins.PlanLayout()); openmct.install(openmct.plugins.Timeline()); + openmct.install(openmct.plugins.Hyperlink()); openmct.install(openmct.plugins.UTCTimeSystem()); openmct.install(openmct.plugins.AutoflowView({ type: "telemetry.panel" diff --git a/package.json b/package.json index 1cde917af5..52ec1f6ace 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "jsdoc": "^3.3.2", "karma": "6.3.4", "karma-chrome-launcher": "3.1.0", - "karma-firefox-launcher": "2.1.0", + "karma-firefox-launcher": "2.1.1", "karma-cli": "2.0.0", "karma-coverage": "2.0.3", "karma-coverage-istanbul-reporter": "3.0.3", diff --git a/platform/features/hyperlink/bundle.js b/platform/features/hyperlink/bundle.js deleted file mode 100644 index d0132ff288..0000000000 --- a/platform/features/hyperlink/bundle.js +++ /dev/null @@ -1,120 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2009-2016, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define([ - './src/HyperlinkController', - './res/templates/hyperlink.html' -], function ( - HyperlinkController, - hyperlinkTemplate -) { - return { - name: "platform/features/hyperlink", - definition: { - "name": "Hyperlink", - "description": "Insert a hyperlink to reference a link", - "extensions": { - "types": [ - { - "key": "hyperlink", - "name": "Hyperlink", - "cssClass": "icon-chain-links", - "description": "A hyperlink to redirect to a different link", - "features": ["creation"], - "properties": [ - { - "key": "url", - "name": "URL", - "control": "textfield", - "required": true, - "cssClass": "l-input-lg" - }, - - { - "key": "displayText", - "name": "Text to Display", - "control": "textfield", - "required": true, - "cssClass": "l-input-lg" - }, - { - "key": "displayFormat", - "name": "Display Format", - "control": "select", - "options": [ - { - "name": "Link", - "value": "link" - }, - { - "value": "button", - "name": "Button" - } - ], - "cssClass": "l-inline" - }, - { - "key": "openNewTab", - "name": "Tab to Open Hyperlink", - "control": "select", - "options": [ - { - "name": "Open in this tab", - "value": "thisTab" - }, - { - "value": "newTab", - "name": "Open in a new tab" - } - ], - "cssClass": "l-inline" - - } - ], - "model": { - "displayFormat": "link", - "openNewTab": "thisTab", - "removeTitle": true - } - - } - ], - "views": [ - { - "key": "hyperlink", - "type": "hyperlink", - "name": "Hyperlink Display", - "template": hyperlinkTemplate, - "editable": false - } - ], - "controllers": [ - { - "key": "HyperlinkController", - "implementation": HyperlinkController, - "depends": ["$scope"] - } - ] - } - } - }; -}); diff --git a/platform/features/hyperlink/res/templates/hyperlink.html b/platform/features/hyperlink/res/templates/hyperlink.html deleted file mode 100644 index 857257fd45..0000000000 --- a/platform/features/hyperlink/res/templates/hyperlink.html +++ /dev/null @@ -1,28 +0,0 @@ - - - {{domainObject.getModel().displayText}} - diff --git a/platform/features/hyperlink/src/HyperlinkController.js b/platform/features/hyperlink/src/HyperlinkController.js deleted file mode 100644 index 42863ed2d9..0000000000 --- a/platform/features/hyperlink/src/HyperlinkController.js +++ /dev/null @@ -1,61 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2009-2016, 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. - *****************************************************************************/ - -/** - * This bundle adds the Hyperlink object type, which can be used to add hyperlinks as a domain Object type - and into display Layouts as either a button or link that can be chosen to open in either the same tab or - create a new tab to open the link in - * @namespace platform/features/hyperlink - */ -define( - [], - function () { - function HyperlinkController($scope) { - this.$scope = $scope; - } - - /**Function to analyze the location in which to open the hyperlink - @returns true if the hyperlink is chosen to open in a different tab, false if the same tab - **/ - HyperlinkController.prototype.openNewTab = function () { - if (this.$scope.domainObject.getModel().openNewTab === "thisTab") { - return false; - } else { - return true; - } - }; - - /**Function to specify the format in which the hyperlink should be created - @returns true if the hyperlink is chosen to be created as a button, false if a link - **/ - HyperlinkController.prototype.isButton = function () { - if (this.$scope.domainObject.getModel().displayFormat === "link") { - return false; - } - - return true; - }; - - return HyperlinkController; - } - -); diff --git a/platform/features/hyperlink/test/HyperlinkControllerSpec.js b/platform/features/hyperlink/test/HyperlinkControllerSpec.js deleted file mode 100644 index 9d66882054..0000000000 --- a/platform/features/hyperlink/test/HyperlinkControllerSpec.js +++ /dev/null @@ -1,89 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2009-2016, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define( - ["../src/HyperlinkController"], - function (HyperlinkController) { - - describe("The controller for hyperlinks", function () { - var domainObject, - controller, - scope; - beforeEach(function () { - scope = jasmine.createSpyObj( - "$scope", - ["domainObject"] - ); - domainObject = jasmine.createSpyObj( - "domainObject", - ["getModel"] - ); - scope.domainObject = domainObject; - controller = new HyperlinkController(scope); - }); - it("knows when it should open a new tab", function () { - scope.domainObject.getModel.and.returnValue({ - "displayFormat": "link", - "openNewTab": "newTab", - "showTitle": false - } - ); - controller = new HyperlinkController(scope); - expect(controller.openNewTab()) - .toBe(true); - }); - it("knows when it is a button", function () { - scope.domainObject.getModel.and.returnValue({ - "displayFormat": "button", - "openNewTab": "thisTab", - "showTitle": false - } - ); - controller = new HyperlinkController(scope); - expect(controller.isButton()) - .toEqual(true); - }); - it("knows when it should open in the same tab", function () { - scope.domainObject.getModel.and.returnValue({ - "displayFormat": "link", - "openNewTab": "thisTab", - "showTitle": false - } - ); - controller = new HyperlinkController(scope); - expect(controller.openNewTab()) - .toBe(false); - }); - it("knows when it is a link", function () { - scope.domainObject.getModel.and.returnValue({ - "displayFormat": "link", - "openNewTab": "thisTab", - "showTitle": false - } - ); - controller = new HyperlinkController(scope); - expect(controller.openNewTab()) - .toBe(false); - }); - }); - } -); diff --git a/src/installDefaultBundles.js b/src/installDefaultBundles.js index 65c0102359..7803f7fa70 100644 --- a/src/installDefaultBundles.js +++ b/src/installDefaultBundles.js @@ -38,7 +38,6 @@ const DEFAULTS = [ 'platform/exporters', 'platform/telemetry', 'platform/features/clock', - 'platform/features/hyperlink', 'platform/forms', 'platform/identity', 'platform/persistence/aggregator', @@ -81,7 +80,6 @@ define([ '../platform/exporters/bundle', '../platform/features/clock/bundle', '../platform/features/my-items/bundle', - '../platform/features/hyperlink/bundle', '../platform/features/static-markup/bundle', '../platform/forms/bundle', '../platform/framework/bundle', diff --git a/src/plugins/hyperlink/HyperlinkLayout.vue b/src/plugins/hyperlink/HyperlinkLayout.vue new file mode 100644 index 0000000000..65ec22e588 --- /dev/null +++ b/src/plugins/hyperlink/HyperlinkLayout.vue @@ -0,0 +1,51 @@ +/***************************************************************************** +* Open MCT, Copyright (c) 2014-2021, 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. +*****************************************************************************/ + + + + diff --git a/src/plugins/hyperlink/HyperlinkProvider.js b/src/plugins/hyperlink/HyperlinkProvider.js new file mode 100644 index 0000000000..d5450a0e55 --- /dev/null +++ b/src/plugins/hyperlink/HyperlinkProvider.js @@ -0,0 +1,63 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, 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 HyperlinkLayout from './HyperlinkLayout.vue'; +import Vue from 'vue'; + +export default function HyperlinkProvider(openmct) { + + return { + key: 'hyperlink.view', + name: 'Hyperlink', + cssClass: 'icon-chain-links', + canView(domainObject) { + return domainObject.type === 'hyperlink'; + }, + + canEdit(domainObject) { + return domainObject.type === 'hyperlink'; + }, + + view: function (domainObject) { + let component; + + return { + show: function (element) { + component = new Vue({ + el: element, + components: { + HyperlinkLayout + }, + provide: { + domainObject + }, + template: '' + }); + }, + destroy: function () { + component.$destroy(); + component = undefined; + } + }; + } + }; +} diff --git a/src/plugins/hyperlink/plugin.js b/src/plugins/hyperlink/plugin.js new file mode 100644 index 0000000000..d89bf8ecdb --- /dev/null +++ b/src/plugins/hyperlink/plugin.js @@ -0,0 +1,89 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2021, 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 HyperlinkProvider from './HyperlinkProvider'; + +export default function () { + return function install(openmct) { + openmct.types.addType('hyperlink', { + name: 'Hyperlink', + key: 'hyperlink', + description: 'A hyperlink to redirect to a different link', + creatable: true, + cssClass: 'icon-chain-links', + initialize: function (domainObject) { + domainObject.displayFormat = "link"; + domainObject.linkTarget = "_self"; + }, + form: [ + { + "key": "url", + "name": "URL", + "control": "textfield", + "required": true, + "cssClass": "l-input-lg" + }, + { + "key": "displayText", + "name": "Text to Display", + "control": "textfield", + "required": true, + "cssClass": "l-input-lg" + }, + { + "key": "displayFormat", + "name": "Display Format", + "control": "select", + "options": [ + { + "name": "Link", + "value": "link" + }, + { + "name": "Button", + "value": "button" + } + ], + "cssClass": "l-inline" + }, + { + "key": "linkTarget", + "name": "Tab to Open Hyperlink", + "control": "select", + "options": [ + { + "name": "Open in this tab", + "value": "_self" + }, + { + "name": "Open in a new tab", + "value": "_blank" + } + ], + "cssClass": "l-inline" + + } + ] + }); + openmct.objectViews.addProvider(new HyperlinkProvider(openmct)); + }; +} diff --git a/src/plugins/hyperlink/pluginSpec.js b/src/plugins/hyperlink/pluginSpec.js new file mode 100644 index 0000000000..e7e5475a62 --- /dev/null +++ b/src/plugins/hyperlink/pluginSpec.js @@ -0,0 +1,130 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2009-2016, 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"; +import HyperlinkPlugin from "./plugin"; + +function getView(openmct, domainObj, objectPath) { + const applicableViews = openmct.objectViews.get(domainObj, objectPath); + const hyperLinkView = applicableViews.find((viewProvider) => viewProvider.key === 'hyperlink.view'); + + return hyperLinkView.view(domainObj); +} + +function destroyView(view) { + return view.destroy(); +} + +describe("The controller for hyperlinks", function () { + let mockDomainObject; + let mockObjectPath; + let openmct; + let element; + let child; + let view; + + beforeEach((done) => { + mockObjectPath = [ + { + name: 'mock hyperlink', + type: 'hyperlink', + identifier: { + key: 'mock-hyperlink', + namespace: '' + } + } + ]; + + mockDomainObject = { + displayFormat: "", + linkTarget: "", + name: "Unnamed HyperLink", + type: "hyperlink", + location: "f69c21ac-24ef-450c-8e2f-3d527087d285", + modified: 1627483839783, + url: "123", + displayText: "123", + persisted: 1627483839783, + id: "3d9c243d-dffb-446b-8474-d9931a99d679", + identifier: { + namespace: "", + key: "3d9c243d-dffb-446b-8474-d9931a99d679" + } + }; + + openmct = createOpenMct(); + openmct.install(new HyperlinkPlugin()); + + element = document.createElement('div'); + element.style.width = '640px'; + element.style.height = '480px'; + child = document.createElement('div'); + child.style.width = '640px'; + child.style.height = '480px'; + element.appendChild(child); + + openmct.on('start', done); + openmct.startHeadless(); + + }); + + afterEach(() => { + destroyView(view); + + return resetApplicationState(openmct); + }); + it("knows when it should open a new tab", () => { + mockDomainObject.displayFormat = "link"; + mockDomainObject.linkTarget = "_blank"; + + view = getView(openmct, mockDomainObject, mockObjectPath); + view.show(child, true); + + expect(element.querySelector('.c-hyperlink').target).toBe('_blank'); + }); + it("knows when it should open in the same tab", function () { + mockDomainObject.displayFormat = "button"; + mockDomainObject.linkTarget = "_self"; + + view = getView(openmct, mockDomainObject, mockObjectPath); + view.show(child, true); + + expect(element.querySelector('.c-hyperlink').target).toBe('_self'); + }); + + it("knows when it is a button", function () { + mockDomainObject.displayFormat = "button"; + + view = getView(openmct, mockDomainObject, mockObjectPath); + view.show(child, true); + + expect(element.querySelector('.c-hyperlink--button')).toBeDefined(); + }); + it("knows when it is a link", function () { + mockDomainObject.displayFormat = "link"; + + view = getView(openmct, mockDomainObject, mockObjectPath); + view.show(child, true); + + expect(element.querySelector('.c-hyperlink')).not.toHaveClass('c-hyperlink--button'); + }); +}); diff --git a/src/plugins/imagery/components/imagery-view-layout.scss b/src/plugins/imagery/components/imagery-view-layout.scss index ac7add83de..532ee33d4f 100644 --- a/src/plugins/imagery/components/imagery-view-layout.scss +++ b/src/plugins/imagery/components/imagery-view-layout.scss @@ -1,7 +1,7 @@ .c-imagery { display: flex; flex-direction: column; - flex: 1 1 auto; + height: 100%; overflow: hidden; &:focus { diff --git a/src/plugins/plugins.js b/src/plugins/plugins.js index 97992bccd7..d38c0868f9 100644 --- a/src/plugins/plugins.js +++ b/src/plugins/plugins.js @@ -67,7 +67,8 @@ define([ './interceptors/plugin', './performanceIndicator/plugin', './CouchDBSearchFolder/plugin', - './timeline/plugin' + './timeline/plugin', + './hyperlink/plugin' ], function ( _, UTCTimeSystem, @@ -115,7 +116,8 @@ define([ ObjectInterceptors, PerformanceIndicator, CouchDBSearchFolder, - Timeline + Timeline, + Hyperlink ) { const bundleMap = { LocalStorage: 'platform/persistence/local', @@ -218,6 +220,7 @@ define([ plugins.PerformanceIndicator = PerformanceIndicator.default; plugins.CouchDBSearchFolder = CouchDBSearchFolder.default; plugins.Timeline = Timeline.default; + plugins.Hyperlink = Hyperlink.default; return plugins; }); diff --git a/src/styles/_controls.scss b/src/styles/_controls.scss index 403711e563..75908cf105 100644 --- a/src/styles/_controls.scss +++ b/src/styles/_controls.scss @@ -445,15 +445,22 @@ select { /******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */ .c-hyperlink { - &--link { - color: $colorKey; - } + display: inline-block; + color: $colorKey; &--button { @include cButton(); } } +.c-so-view--no-frame > .c-so-view__object-view > .c-hyperlink--button { + @include abs(); + display: flex; + align-items: center; + justify-content: center; + padding: 0; +} + /******************************************************** MENUS */ @mixin menuOuter() { border-radius: $basicCr; diff --git a/src/ui/components/object-frame.scss b/src/ui/components/object-frame.scss index 74094fb1a6..36b9188ff6 100644 --- a/src/ui/components/object-frame.scss +++ b/src/ui/components/object-frame.scss @@ -138,22 +138,11 @@ &.is-status--missing { border: $borderMissing; } - - &__object-view { - display: flex; - flex: 1 1 auto; - overflow: auto; - - .u-fills-container { - // Expand component types that fill a container - @include abs(); - } - } } .l-angular-ov-wrapper { // This element is the recipient for object styling; cannot be display: contents - flex: 1 1 auto; overflow: hidden; display: block; + height: 100%; } diff --git a/src/ui/layout/layout.scss b/src/ui/layout/layout.scss index 751494860f..702bf08866 100644 --- a/src/ui/layout/layout.scss +++ b/src/ui/layout/layout.scss @@ -234,7 +234,7 @@ /******************************* MAIN AREA */ &__main-container { // Wrapper for main views - display: flex; + //display: flex; NEEDS REGRESSION TESTING!!! flex: 1 1 auto !important; height: 100%; // Chrome 73 overflow bug fix overflow: auto; diff --git a/src/ui/preview/preview.scss b/src/ui/preview/preview.scss index b8cd2462c3..418c19175b 100644 --- a/src/ui/preview/preview.scss +++ b/src/ui/preview/preview.scss @@ -13,7 +13,6 @@ } &__object-view { - display: flex; flex: 1 1 auto; height: 100%; // Chrome 73 overflow: auto;