From bacad248110e846f0e56b3ca1529a393c078256b Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Fri, 10 Jul 2020 13:27:30 -0700 Subject: [PATCH 01/19] Delete telemetry cache only when count reaches 0 --- src/api/telemetry/TelemetryAPI.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/telemetry/TelemetryAPI.js b/src/api/telemetry/TelemetryAPI.js index 41c49e4027..8c5d473bc8 100644 --- a/src/api/telemetry/TelemetryAPI.js +++ b/src/api/telemetry/TelemetryAPI.js @@ -334,8 +334,8 @@ define([ }); if (subscriber.callbacks.length === 0) { subscriber.unsubscribe(); + delete this.subscribeCache[keyString]; } - delete this.subscribeCache[keyString]; }.bind(this); }; From 98db273f5d26092c5f433068ce4155f574fe11a0 Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Fri, 10 Jul 2020 15:10:33 -0700 Subject: [PATCH 02/19] Remove unsubscribe callback --- src/plugins/condition/StyleRuleManager.js | 4 +++- .../condition/components/inspector/ConditionalStylesView.vue | 4 ++++ src/plugins/condition/components/inspector/StylesView.vue | 4 ++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/plugins/condition/StyleRuleManager.js b/src/plugins/condition/StyleRuleManager.js index 6fe7b38c37..33482c2fe8 100644 --- a/src/plugins/condition/StyleRuleManager.js +++ b/src/plugins/condition/StyleRuleManager.js @@ -46,6 +46,7 @@ export default class StyleRuleManager extends EventEmitter { if (this.isEditing) { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } if (this.conditionSetIdentifier) { this.applySelectedConditionStyle(); @@ -66,6 +67,7 @@ export default class StyleRuleManager extends EventEmitter { subscribeToConditionSet() { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } this.openmct.objects.get(this.conditionSetIdentifier).then((conditionSetDomainObject) => { this.openmct.telemetry.request(conditionSetDomainObject) @@ -154,8 +156,8 @@ export default class StyleRuleManager extends EventEmitter { this.applyStaticStyle(); if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } - delete this.stopProvidingTelemetry; this.conditionSetIdentifier = undefined; } diff --git a/src/plugins/condition/components/inspector/ConditionalStylesView.vue b/src/plugins/condition/components/inspector/ConditionalStylesView.vue index cd99ea8fb0..64700ed143 100644 --- a/src/plugins/condition/components/inspector/ConditionalStylesView.vue +++ b/src/plugins/condition/components/inspector/ConditionalStylesView.vue @@ -197,6 +197,7 @@ export default { } if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } }, initialize(conditionSetDomainObject) { @@ -210,6 +211,7 @@ export default { if (this.isEditing) { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } } else { this.subscribeToConditionSet(); @@ -307,6 +309,7 @@ export default { this.persist(domainObjectStyles); if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } }, updateDomainObjectItemStyles(newItems) { @@ -375,6 +378,7 @@ export default { subscribeToConditionSet() { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } if (this.conditionSetDomainObject) { this.openmct.telemetry.request(this.conditionSetDomainObject) diff --git a/src/plugins/condition/components/inspector/StylesView.vue b/src/plugins/condition/components/inspector/StylesView.vue index 35cb7ad169..33f495de92 100644 --- a/src/plugins/condition/components/inspector/StylesView.vue +++ b/src/plugins/condition/components/inspector/StylesView.vue @@ -190,6 +190,7 @@ export default { if (this.isEditing) { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } } else { this.subscribeToConditionSet(); @@ -325,6 +326,7 @@ export default { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } if (this.unObserveObjects) { @@ -337,6 +339,7 @@ export default { subscribeToConditionSet() { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } if (this.conditionSetDomainObject) { this.openmct.telemetry.request(this.conditionSetDomainObject) @@ -494,6 +497,7 @@ export default { if (this.stopProvidingTelemetry) { this.stopProvidingTelemetry(); + delete this.stopProvidingTelemetry; } }, removeConditionalStyles(domainObjectStyles, itemId) { From 894da25461c1dc30800a9bc7aa8f4fbc102dc260 Mon Sep 17 00:00:00 2001 From: charlesh88 Date: Tue, 14 Jul 2020 18:42:52 -0700 Subject: [PATCH 03/19] Fix Safari display issues #3192 - Fix Inspector `__content` to properly use flex column layout; - Change `u-angular-object-view-wrapper` to `display: contents`; - Fix `gl-plot` to properly use `flex: 1 1 auto` instead of width and height; --- src/styles/_legacy-plots.scss | 4 +--- src/ui/components/object-frame.scss | 13 ++++--------- src/ui/inspector/inspector.scss | 4 +++- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/styles/_legacy-plots.scss b/src/styles/_legacy-plots.scss index e02e449204..bd8c12710d 100644 --- a/src/styles/_legacy-plots.scss +++ b/src/styles/_legacy-plots.scss @@ -118,9 +118,7 @@ mct-plot { .gl-plot { display: flex; - position: relative; - width: 100%; - height: 100%; + flex: 1 1 auto; /*********************** AXIS AND DISPLAY AREA */ .plot-wrapper-axis-and-display-area { diff --git a/src/ui/components/object-frame.scss b/src/ui/components/object-frame.scss index dd1d17f654..f36eb6e678 100644 --- a/src/ui/components/object-frame.scss +++ b/src/ui/components/object-frame.scss @@ -74,11 +74,9 @@ height: 0; // Chrome 73 overflow bug fix overflow: auto; - .u-angular-object-view-wrapper { - .u-fills-container { - // Expand component types that fill a container - @include abs(); - } + .u-fills-container { + // Expand component types that fill a container + @include abs(); } } @@ -91,8 +89,5 @@ } .u-angular-object-view-wrapper { - flex: 1 1 auto; - height: 100%; - width: 100%; - overflow: hidden; + display: contents; } diff --git a/src/ui/inspector/inspector.scss b/src/ui/inspector/inspector.scss index cd5b56107a..528e6ead24 100644 --- a/src/ui/inspector/inspector.scss +++ b/src/ui/inspector/inspector.scss @@ -4,7 +4,7 @@ flex-direction: column; > * { - // Thi is on purpose: want extra margin on top object-name element + // This is on purpose: want extra margin on top object-name element margin-top: $interiorMargin; } @@ -41,6 +41,8 @@ &__content { flex: 1 1 auto; + display: flex; + flex-direction: column; } &__elements { From 8b088b7a2c1df097eb4c47506c69df662b9c1b9b Mon Sep 17 00:00:00 2001 From: charlesh88 Date: Tue, 14 Jul 2020 18:53:30 -0700 Subject: [PATCH 04/19] Fix Safari display issues #3192 - Fix Status area indicators width problem; - Also fixes collapsing-status-area-indicator-bubbles transition problem as well!; --- src/ui/layout/status-bar/indicators.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ui/layout/status-bar/indicators.scss b/src/ui/layout/status-bar/indicators.scss index 67001aeb73..10955bc94d 100644 --- a/src/ui/layout/status-bar/indicators.scss +++ b/src/ui/layout/status-bar/indicators.scss @@ -76,8 +76,12 @@ [class*='minify-indicators'] { // All styles for minified Indicators should go in here .c-indicator:not(.no-minify) { + overflow: hidden; // Solves width problem in Safari as well as collapsing bubbles problem + @include hover() { background: $colorIndicatorBgHov; + overflow: visible; + .c-indicator__label { box-shadow: $colorIndicatorMenuBgShdw; transform: scale(1.0); From 73b81e38e736ec7fc435958e8abf92f7f9e4bd0c Mon Sep 17 00:00:00 2001 From: charlesh88 Date: Tue, 14 Jul 2020 19:22:18 -0700 Subject: [PATCH 05/19] Fix Safari display issues #3192 - Fix collapsed Status area indicators width problem; --- src/ui/layout/status-bar/indicators.scss | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/ui/layout/status-bar/indicators.scss b/src/ui/layout/status-bar/indicators.scss index 10955bc94d..1d33692662 100644 --- a/src/ui/layout/status-bar/indicators.scss +++ b/src/ui/layout/status-bar/indicators.scss @@ -76,16 +76,19 @@ [class*='minify-indicators'] { // All styles for minified Indicators should go in here .c-indicator:not(.no-minify) { - overflow: hidden; // Solves width problem in Safari as well as collapsing bubbles problem + border: 1px solid transparent; // Hack to make minified sizing work in Safari. Have no idea why this works. + overflow: visible; + transition: all; @include hover() { background: $colorIndicatorBgHov; - overflow: visible; + transition: all 250ms ease-in 200ms; .c-indicator__label { box-shadow: $colorIndicatorMenuBgShdw; transform: scale(1.0); - transition: all 100ms ease-out 100ms; + overflow: visible; + //transition: all 100ms ease-out 100ms; } } .c-indicator__label { @@ -99,7 +102,7 @@ position: absolute; transform-origin: 90% 0; transform: scale(0.0); - overflow: visible; + overflow: hidden; z-index: 50; &:before { From baa7c0bc584a22162e6c2d972346670bb8851a1d Mon Sep 17 00:00:00 2001 From: charlesh88 Date: Tue, 14 Jul 2020 21:51:22 -0700 Subject: [PATCH 06/19] Fix Safari display issues #3192 - Tweak to Status area indicator hover bubbles; --- src/ui/layout/status-bar/indicators.scss | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ui/layout/status-bar/indicators.scss b/src/ui/layout/status-bar/indicators.scss index 1d33692662..ce334d3c24 100644 --- a/src/ui/layout/status-bar/indicators.scss +++ b/src/ui/layout/status-bar/indicators.scss @@ -78,21 +78,21 @@ .c-indicator:not(.no-minify) { border: 1px solid transparent; // Hack to make minified sizing work in Safari. Have no idea why this works. overflow: visible; - transition: all; + transition: transform; @include hover() { background: $colorIndicatorBgHov; - transition: all 250ms ease-in 200ms; + transition: transform 250ms ease-in 200ms; // Go-away transition .c-indicator__label { box-shadow: $colorIndicatorMenuBgShdw; transform: scale(1.0); overflow: visible; - //transition: all 100ms ease-out 100ms; + transition: transform 100ms ease-out 100ms; // Appear transition } } .c-indicator__label { - transition: all 250ms ease-in 200ms; + transition: transform 250ms ease-in 200ms; // Go-away transition background: $colorIndicatorMenuBg; color: $colorIndicatorMenuFg; border-radius: $controlCr; From b1467548da489c9a8176b47f70fd2adc1cf71179 Mon Sep 17 00:00:00 2001 From: charlesh88 Date: Tue, 14 Jul 2020 23:40:42 -0700 Subject: [PATCH 07/19] Fix Safari display issues #3192 - Tweaks to fix `c-tab` elements, fix clip-path for webkit; - Fix Notebook Snapshots header; --- .../notebook-snapshot-container.vue | 17 +++++++------ src/styles/_controls.scss | 24 ++++++++++--------- src/ui/components/object-label.scss | 3 +-- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/plugins/notebook/components/notebook-snapshot-container.vue b/src/plugins/notebook/components/notebook-snapshot-container.vue index 950f655ba3..8dcbba0f64 100644 --- a/src/plugins/notebook/components/notebook-snapshot-container.vue +++ b/src/plugins/notebook/components/notebook-snapshot-container.vue @@ -2,13 +2,16 @@
-
-
- Notebook Snapshots -  {{ snapshots.length }} of {{ getNotebookSnapshotMaxCount() }} - +
+
+
+
+ Notebook Snapshots +  {{ snapshots.length }} of {{ getNotebookSnapshotMaxCount() }} + +
* + * { margin-left: $interiorMargin; diff --git a/src/ui/components/object-label.scss b/src/ui/components/object-label.scss index 3181f23a31..395c223086 100644 --- a/src/ui/components/object-label.scss +++ b/src/ui/components/object-label.scss @@ -3,7 +3,7 @@ // Used mostly in trees and lists display: flex; align-items: center; - flex: 1 1 auto; + flex: 0 1 auto; overflow: hidden; white-space: nowrap; @@ -19,7 +19,6 @@ display: block; flex: 0 0 auto; font-size: 1.1em; - //margin-right: $interiorMargin; } &.is-missing { From 16bb22e834ab7f9aaf2c0de8917ec2dbf74bb46d Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Thu, 16 Jul 2020 11:50:03 -0700 Subject: [PATCH 08/19] Added regression test --- src/api/telemetry/TelemetryAPISpec.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/api/telemetry/TelemetryAPISpec.js b/src/api/telemetry/TelemetryAPISpec.js index 3429afb083..efbeb40e40 100644 --- a/src/api/telemetry/TelemetryAPISpec.js +++ b/src/api/telemetry/TelemetryAPISpec.js @@ -156,6 +156,29 @@ define([ expect(callbacktwo).not.toHaveBeenCalledWith('anotherValue'); }); + it('only deletes subscription cache when there are no more subscribers', function () { + var unsubFunc = jasmine.createSpy('unsubscribe'); + telemetryProvider.subscribe.and.returnValue(unsubFunc); + telemetryProvider.supportsSubscribe.and.returnValue(true); + telemetryAPI.addProvider(telemetryProvider); + + var callback = jasmine.createSpy('callback'); + var callbacktwo = jasmine.createSpy('callback two'); + var callbackThree = jasmine.createSpy('callback three'); + var unsubscribe = telemetryAPI.subscribe(domainObject, callback); + var unsubscribeTwo = telemetryAPI.subscribe(domainObject, callbacktwo); + + expect(telemetryProvider.subscribe.calls.count()).toBe(1); + unsubscribe(); + var unsubscribeThree = telemetryAPI.subscribe(domainObject, callbackThree); + // Regression test for where subscription cache was deleted on each unsubscribe, resulting in + // superfluous additional subscriptions. If the subscription cache is being deleted on each unsubscribe, + // then a subsequent subscribe will result in a new subscription at the provider. + expect(telemetryProvider.subscribe.calls.count()).toBe(1); + unsubscribeTwo(); + unsubscribeThree(); + }); + it('does subscribe/unsubscribe', function () { var unsubFunc = jasmine.createSpy('unsubscribe'); telemetryProvider.subscribe.and.returnValue(unsubFunc); From cb63f4eca1b092bead15332650f00cc2a313d576 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Thu, 16 Jul 2020 12:43:37 -0700 Subject: [PATCH 09/19] Fix `is-missing` layout problem #3194 (#3195) - Fixes related to `is-missing` including fixes for Display Layout alphanumeric views and Tabs view tabs; --- .../components/telemetry-view.scss | 15 ++++++------- src/plugins/tabs/components/tabs.vue | 21 +++++++++++-------- src/styles/_mixins.scss | 5 ++++- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/plugins/displayLayout/components/telemetry-view.scss b/src/plugins/displayLayout/components/telemetry-view.scss index 075ded5273..22ea9a90b4 100644 --- a/src/plugins/displayLayout/components/telemetry-view.scss +++ b/src/plugins/displayLayout/components/telemetry-view.scss @@ -27,13 +27,14 @@ border: 1px solid transparent; } - &.is-missing { - @include isMissing($absPos: true); - border: $borderMissing; + @include isMissing($absPos: true); - .is-missing__indicator { - top: 0; - left: 0; - } + .is-missing__indicator { + top: 0; + left: 0; + } + + &.is-missing { + border: $borderMissing; } } diff --git a/src/plugins/tabs/components/tabs.vue b/src/plugins/tabs/components/tabs.vue index 0d32867131..294ba41470 100644 --- a/src/plugins/tabs/components/tabs.vue +++ b/src/plugins/tabs/components/tabs.vue @@ -22,21 +22,24 @@
Date: Fri, 17 Jul 2020 09:23:51 -0700 Subject: [PATCH 10/19] Disallow editor Edit mode when object is locked (#3208) * Don't allow editor edit if object is locked * Adds log statement * Use capture phase for onDragOver Co-authored-by: Deep Tailor --- src/ui/components/ObjectView.vue | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/components/ObjectView.vue b/src/ui/components/ObjectView.vue index 870cc34d4d..1685a8fdd3 100644 --- a/src/ui/components/ObjectView.vue +++ b/src/ui/components/ObjectView.vue @@ -53,7 +53,9 @@ export default { mounted() { this.currentObject = this.object; this.updateView(); - this.$el.addEventListener('dragover', this.onDragOver); + this.$el.addEventListener('dragover', this.onDragOver, { + capture: true + }); this.$el.addEventListener('drop', this.editIfEditable, { capture: true }); @@ -269,6 +271,7 @@ export default { if (provider && provider.canEdit && provider.canEdit(this.currentObject) && + this.isEditingAllowed() && !this.openmct.editor.isEditing()) { this.openmct.editor.edit(); } From 63bf856d89ce8bf02e90e3b6b97b941aa6859645 Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Fri, 17 Jul 2020 09:58:03 -0700 Subject: [PATCH 11/19] Enable persistence operations from Object Providers (#3200) * Implement 'save' method in Object API * Refactor legacy persistence code to work with new save object API * Added 'isPersistable' check to object API * Fixed incompatibility between object API changes and composition policies * Make save method private Co-authored-by: Deep Tailor --- .../policies/EditPersistableObjectsPolicy.js | 7 +- .../policies/EditPersistableObjectsSpec.js | 23 +++--- .../src/PersistableCompositionPolicy.js | 5 +- .../test/PersistableCompositionPolicySpec.js | 15 ++-- platform/core/bundle.js | 3 +- .../src/capabilities/PersistenceCapability.js | 46 ++++------- .../capabilities/PersistenceCapabilitySpec.js | 82 +++++++++---------- .../services/LegacyObjectAPIInterceptor.js | 57 +++++++++++-- src/api/objects/ObjectAPI.js | 60 ++++++++++++-- src/api/objects/ObjectAPISpec.js | 60 ++++++++++++++ 10 files changed, 238 insertions(+), 120 deletions(-) create mode 100644 src/api/objects/ObjectAPISpec.js diff --git a/platform/commonUI/edit/src/policies/EditPersistableObjectsPolicy.js b/platform/commonUI/edit/src/policies/EditPersistableObjectsPolicy.js index e384e4970a..50a0dc7a9b 100644 --- a/platform/commonUI/edit/src/policies/EditPersistableObjectsPolicy.js +++ b/platform/commonUI/edit/src/policies/EditPersistableObjectsPolicy.js @@ -36,8 +36,6 @@ define( } EditPersistableObjectsPolicy.prototype.allow = function (action, context) { - var identifier; - var provider; var domainObject = context.domainObject; var key = action.getMetadata().key; var category = (context || {}).category; @@ -46,9 +44,8 @@ define( // is also invoked during the create process which should be allowed, // because it may be saved elsewhere if ((key === 'edit' && category === 'view-control') || key === 'properties') { - identifier = objectUtils.parseKeyString(domainObject.getId()); - provider = this.openmct.objects.getProvider(identifier); - return provider.save !== undefined; + let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId()); + return this.openmct.objects.isPersistable(newStyleObject); } return true; diff --git a/platform/commonUI/edit/test/policies/EditPersistableObjectsSpec.js b/platform/commonUI/edit/test/policies/EditPersistableObjectsSpec.js index ed9c61bf1d..92b0da2d36 100644 --- a/platform/commonUI/edit/test/policies/EditPersistableObjectsSpec.js +++ b/platform/commonUI/edit/test/policies/EditPersistableObjectsSpec.js @@ -43,7 +43,7 @@ define( ); mockObjectAPI = jasmine.createSpyObj('objectAPI', [ - 'getProvider' + 'isPersistable' ]); mockAPI = { @@ -69,34 +69,31 @@ define( }); it("Applies to edit action", function () { - mockObjectAPI.getProvider.and.returnValue({}); - expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).not.toHaveBeenCalled(); policy.allow(mockEditAction, testContext); - expect(mockObjectAPI.getProvider).toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).toHaveBeenCalled(); }); it("Applies to properties action", function () { - mockObjectAPI.getProvider.and.returnValue({}); - expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).not.toHaveBeenCalled(); policy.allow(mockPropertiesAction, testContext); - expect(mockObjectAPI.getProvider).toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).toHaveBeenCalled(); }); it("does not apply to other actions", function () { - mockObjectAPI.getProvider.and.returnValue({}); - expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).not.toHaveBeenCalled(); policy.allow(mockOtherAction, testContext); - expect(mockObjectAPI.getProvider).not.toHaveBeenCalled(); + expect(mockObjectAPI.isPersistable).not.toHaveBeenCalled(); }); it("Tests object provider for editability", function () { - mockObjectAPI.getProvider.and.returnValue({}); + mockObjectAPI.isPersistable.and.returnValue(false); expect(policy.allow(mockEditAction, testContext)).toBe(false); - expect(mockObjectAPI.getProvider).toHaveBeenCalled(); - mockObjectAPI.getProvider.and.returnValue({save: function () {}}); + expect(mockObjectAPI.isPersistable).toHaveBeenCalled(); + mockObjectAPI.isPersistable.and.returnValue(true); expect(policy.allow(mockEditAction, testContext)).toBe(true); }); }); diff --git a/platform/containment/src/PersistableCompositionPolicy.js b/platform/containment/src/PersistableCompositionPolicy.js index df9d228222..bb8c4078ac 100644 --- a/platform/containment/src/PersistableCompositionPolicy.js +++ b/platform/containment/src/PersistableCompositionPolicy.js @@ -48,9 +48,8 @@ define( // prevents editing of objects that cannot be persisted, so we can assume that this // is a new object. if (!(parent.hasCapability('editor') && parent.getCapability('editor').isEditContextRoot())) { - var identifier = objectUtils.parseKeyString(parent.getId()); - var provider = this.openmct.objects.getProvider(identifier); - return provider.save !== undefined; + let newStyleObject = objectUtils.toNewFormat(parent, parent.getId()); + return this.openmct.objects.isPersistable(newStyleObject); } return true; }; diff --git a/platform/containment/test/PersistableCompositionPolicySpec.js b/platform/containment/test/PersistableCompositionPolicySpec.js index f06ef7d16b..dcc2a928a5 100644 --- a/platform/containment/test/PersistableCompositionPolicySpec.js +++ b/platform/containment/test/PersistableCompositionPolicySpec.js @@ -33,7 +33,7 @@ define( beforeEach(function () { objectAPI = jasmine.createSpyObj('objectsAPI', [ - 'getProvider' + 'isPersistable' ]); mockOpenMCT = { @@ -51,10 +51,6 @@ define( 'isEditContextRoot' ]); mockParent.getCapability.and.returnValue(mockEditorCapability); - - objectAPI.getProvider.and.returnValue({ - save: function () {} - }); persistableCompositionPolicy = new PersistableCompositionPolicy(mockOpenMCT); }); @@ -65,19 +61,22 @@ define( it("Does not allow composition for objects that are not persistable", function () { mockEditorCapability.isEditContextRoot.and.returnValue(false); + objectAPI.isPersistable.and.returnValue(true); expect(persistableCompositionPolicy.allow(mockParent, mockChild)).toBe(true); - objectAPI.getProvider.and.returnValue({}); + objectAPI.isPersistable.and.returnValue(false); expect(persistableCompositionPolicy.allow(mockParent, mockChild)).toBe(false); }); it("Always allows composition of objects in edit mode to support object creation", function () { mockEditorCapability.isEditContextRoot.and.returnValue(true); + objectAPI.isPersistable.and.returnValue(true); expect(persistableCompositionPolicy.allow(mockParent, mockChild)).toBe(true); - expect(objectAPI.getProvider).not.toHaveBeenCalled(); + expect(objectAPI.isPersistable).not.toHaveBeenCalled(); mockEditorCapability.isEditContextRoot.and.returnValue(false); + objectAPI.isPersistable.and.returnValue(true); expect(persistableCompositionPolicy.allow(mockParent, mockChild)).toBe(true); - expect(objectAPI.getProvider).toHaveBeenCalled(); + expect(objectAPI.isPersistable).toHaveBeenCalled(); }); }); diff --git a/platform/core/bundle.js b/platform/core/bundle.js index 487a009581..30f8ee9303 100644 --- a/platform/core/bundle.js +++ b/platform/core/bundle.js @@ -297,7 +297,8 @@ define([ "persistenceService", "identifierService", "notificationService", - "$q" + "$q", + "openmct" ] }, { diff --git a/platform/core/src/capabilities/PersistenceCapability.js b/platform/core/src/capabilities/PersistenceCapability.js index 7b1658e66e..12ec5e275c 100644 --- a/platform/core/src/capabilities/PersistenceCapability.js +++ b/platform/core/src/capabilities/PersistenceCapability.js @@ -20,8 +20,8 @@ * at runtime from the About dialog for additional information. *****************************************************************************/ -define( - function () { +define(["objectUtils"], + function (objectUtils) { /** * Defines the `persistence` capability, used to trigger the @@ -47,6 +47,7 @@ define( identifierService, notificationService, $q, + openmct, domainObject ) { // Cache modified timestamp @@ -58,6 +59,7 @@ define( this.persistenceService = persistenceService; this.notificationService = notificationService; this.$q = $q; + this.openmct = openmct; } /** @@ -66,7 +68,7 @@ define( */ function rejectIfFalsey(value, $q) { if (!value) { - return $q.reject("Error persisting object"); + return Promise.reject("Error persisting object"); } else { return value; } @@ -98,7 +100,7 @@ define( dismissable: true }); - return $q.reject(error); + return Promise.reject(error); } /** @@ -110,34 +112,16 @@ define( */ PersistenceCapability.prototype.persist = function () { var self = this, - domainObject = this.domainObject, - model = domainObject.getModel(), - modified = model.modified, - persisted = model.persisted, - persistenceService = this.persistenceService, - persistenceFn = persisted !== undefined ? - this.persistenceService.updateObject : - this.persistenceService.createObject; + domainObject = this.domainObject; - if (persisted !== undefined && persisted === modified) { - return this.$q.when(true); - } - - // Update persistence timestamp... - domainObject.useCapability("mutation", function (m) { - m.persisted = modified; - }, modified); - - // ...and persist - return persistenceFn.apply(persistenceService, [ - this.getSpace(), - this.getKey(), - domainObject.getModel() - ]).then(function (result) { - return rejectIfFalsey(result, self.$q); - }).catch(function (error) { - return notifyOnError(error, domainObject, self.notificationService, self.$q); - }); + let newStyleObject = objectUtils.toNewFormat(domainObject.getModel(), domainObject.getId()); + return this.openmct.objects + .save(newStyleObject) + .then(function (result) { + return rejectIfFalsey(result, self.$q); + }).catch(function (error) { + return notifyOnError(error, domainObject, self.notificationService, self.$q); + }); }; /** diff --git a/platform/core/test/capabilities/PersistenceCapabilitySpec.js b/platform/core/test/capabilities/PersistenceCapabilitySpec.js index aa112fb8cf..68fd84092d 100644 --- a/platform/core/test/capabilities/PersistenceCapabilitySpec.js +++ b/platform/core/test/capabilities/PersistenceCapabilitySpec.js @@ -19,7 +19,6 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ - /** * PersistenceCapabilitySpec. Created by vwoeltje on 11/6/14. */ @@ -40,7 +39,8 @@ define( model, SPACE = "some space", persistence, - happyPromise; + mockOpenMCT, + mockNewStyleDomainObject; function asPromise(value, doCatch) { return (value || {}).then ? value : { @@ -56,7 +56,6 @@ define( } beforeEach(function () { - happyPromise = asPromise(true); model = { someKey: "some value", name: "domain object"}; mockPersistenceService = jasmine.createSpyObj( @@ -94,12 +93,23 @@ define( }, useCapability: jasmine.createSpy() }; + + mockNewStyleDomainObject = Object.assign({}, model); + mockNewStyleDomainObject.identifier = { + namespace: "", + key: id + } + // Simulate mutation capability mockDomainObject.useCapability.and.callFake(function (capability, mutator) { if (capability === 'mutation') { model = mutator(model) || model; } }); + + mockOpenMCT = {}; + mockOpenMCT.objects = jasmine.createSpyObj('Object API', ['save']); + mockIdentifierService.parse.and.returnValue(mockIdentifier); mockIdentifier.getSpace.and.returnValue(SPACE); mockIdentifier.getKey.and.returnValue(key); @@ -110,51 +120,28 @@ define( mockIdentifierService, mockNofificationService, mockQ, + mockOpenMCT, mockDomainObject ); }); describe("successful persistence", function () { beforeEach(function () { - mockPersistenceService.updateObject.and.returnValue(happyPromise); - mockPersistenceService.createObject.and.returnValue(happyPromise); + mockOpenMCT.objects.save.and.returnValue(Promise.resolve(true)); }); it("creates unpersisted objects with the persistence service", function () { // Verify precondition; no call made during constructor - expect(mockPersistenceService.createObject).not.toHaveBeenCalled(); + expect(mockOpenMCT.objects.save).not.toHaveBeenCalled(); persistence.persist(); - expect(mockPersistenceService.createObject).toHaveBeenCalledWith( - SPACE, - key, - model - ); - }); - - it("updates previously persisted objects with the persistence service", function () { - // Verify precondition; no call made during constructor - expect(mockPersistenceService.updateObject).not.toHaveBeenCalled(); - - model.persisted = 12321; - persistence.persist(); - - expect(mockPersistenceService.updateObject).toHaveBeenCalledWith( - SPACE, - key, - model - ); + expect(mockOpenMCT.objects.save).toHaveBeenCalledWith(mockNewStyleDomainObject); }); it("reports which persistence space an object belongs to", function () { expect(persistence.getSpace()).toEqual(SPACE); }); - it("updates persisted timestamp on persistence", function () { - model.modified = 12321; - persistence.persist(); - expect(model.persisted).toEqual(12321); - }); it("refreshes the domain object model from persistence", function () { var refreshModel = {someOtherKey: "some other value"}; model.persisted = 1; @@ -165,30 +152,37 @@ define( it("does not trigger error notification on successful" + " persistence", function () { - persistence.persist(); - expect(mockQ.reject).not.toHaveBeenCalled(); - expect(mockNofificationService.error).not.toHaveBeenCalled(); + let rejected = false; + return persistence.persist() + .catch(() => rejected = true) + .then(() => { + expect(rejected).toBe(false); + expect(mockNofificationService.error).not.toHaveBeenCalled(); + }); }); }); describe("unsuccessful persistence", function () { - var sadPromise = { - then: function (callback) { - return asPromise(callback(0), true); - } - }; beforeEach(function () { - mockPersistenceService.createObject.and.returnValue(sadPromise); + mockOpenMCT.objects.save.and.returnValue(Promise.resolve(false)); }); it("rejects on falsey persistence result", function () { - persistence.persist(); - expect(mockQ.reject).toHaveBeenCalled(); + let rejected = false; + return persistence.persist() + .catch(() => rejected = true) + .then(() => { + expect(rejected).toBe(true); + }); }); it("notifies user on persistence failure", function () { - persistence.persist(); - expect(mockQ.reject).toHaveBeenCalled(); - expect(mockNofificationService.error).toHaveBeenCalled(); + let rejected = false; + return persistence.persist() + .catch(() => rejected = true) + .then(() => { + expect(rejected).toBe(true); + expect(mockNofificationService.error).toHaveBeenCalled(); + }); }); }); }); diff --git a/src/adapter/services/LegacyObjectAPIInterceptor.js b/src/adapter/services/LegacyObjectAPIInterceptor.js index d71dcd1837..5448f50c82 100644 --- a/src/adapter/services/LegacyObjectAPIInterceptor.js +++ b/src/adapter/services/LegacyObjectAPIInterceptor.js @@ -25,10 +25,11 @@ define([ ], function ( utils ) { - function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic) { + function ObjectServiceProvider(eventEmitter, objectService, instantiate, topic, $injector) { this.eventEmitter = eventEmitter; this.objectService = objectService; this.instantiate = instantiate; + this.$injector = $injector; this.generalTopic = topic('mutation'); this.bridgeEventBuses(); @@ -68,16 +69,53 @@ define([ removeGeneralTopicListener = this.generalTopic.listen(handleLegacyMutation); }; - ObjectServiceProvider.prototype.save = function (object) { - var key = object.key; + ObjectServiceProvider.prototype.create = async function (object) { + let model = utils.toOldFormat(object); - return object.getCapability('persistence') - .persist() - .then(function () { - return utils.toNewFormat(object, key); - }); + return this.getPersistenceService().createObject( + this.getSpace(utils.makeKeyString(object.identifier)), + object.identifier.key, + model + ); + } + ObjectServiceProvider.prototype.update = async function (object) { + let model = utils.toOldFormat(object); + + return this.getPersistenceService().updateObject( + this.getSpace(utils.makeKeyString(object.identifier)), + object.identifier.key, + model + ); + } + + /** + * Get the space in which this domain object is persisted; + * this is useful when, for example, decided which space a + * newly-created domain object should be persisted to (by + * default, this should be the space of its containing + * object.) + * + * @returns {string} the name of the space which should + * be used to persist this object + */ + ObjectServiceProvider.prototype.getSpace = function (keystring) { + return this.getIdentifierService().parse(keystring).getSpace(); }; + ObjectServiceProvider.prototype.getIdentifierService = function () { + if (this.identifierService === undefined) { + this.identifierService = this.$injector.get('identifierService'); + } + return this.identifierService; + }; + + ObjectServiceProvider.prototype.getPersistenceService = function () { + if (this.persistenceService === undefined) { + this.persistenceService = this.$injector.get('persistenceService'); + } + return this.persistenceService; + } + ObjectServiceProvider.prototype.delete = function (object) { // TODO! }; @@ -118,7 +156,8 @@ define([ eventEmitter, objectService, instantiate, - topic + topic, + openmct.$injector ) ); diff --git a/src/api/objects/ObjectAPI.js b/src/api/objects/ObjectAPI.js index 3d874eb295..914620607b 100644 --- a/src/api/objects/ObjectAPI.js +++ b/src/api/objects/ObjectAPI.js @@ -101,14 +101,25 @@ define([ */ /** - * Save this domain object in its current state. + * Create the given domain object in the corresponding persistence store * - * @method save + * @method create * @memberof module:openmct.ObjectProvider# * @param {module:openmct.DomainObject} domainObject the domain object to - * save + * create * @returns {Promise} a promise which will resolve when the domain object - * has been saved, or be rejected if it cannot be saved + * has been created, or be rejected if it cannot be saved + */ + + /** + * Update this domain object in its persistence store + * + * @method update + * @memberof module:openmct.ObjectProvider# + * @param {module:openmct.DomainObject} domainObject the domain object to + * update + * @returns {Promise} a promise which will resolve when the domain object + * has been updated, or be rejected if it cannot be saved */ /** @@ -161,8 +172,41 @@ define([ throw new Error('Delete not implemented'); }; - ObjectAPI.prototype.save = function () { - throw new Error('Save not implemented'); + ObjectAPI.prototype.isPersistable = function (domainObject) { + let provider = this.getProvider(domainObject.identifier); + return provider !== undefined && + provider.create !== undefined && + provider.update !== undefined; + } + + /** + * Save this domain object in its current state. EXPERIMENTAL + * + * @private + * @memberof module:openmct.ObjectAPI# + * @param {module:openmct.DomainObject} domainObject the domain object to + * save + * @returns {Promise} a promise which will resolve when the domain object + * has been saved, or be rejected if it cannot be saved + */ + ObjectAPI.prototype.save = function (domainObject) { + let provider = this.getProvider(domainObject.identifier); + let result; + + if (!this.isPersistable(domainObject)) { + result = Promise.reject('Object provider does not support saving'); + } else if (hasAlreadyBeenPersisted(domainObject)) { + result = Promise.resolve(true); + } else { + if (domainObject.persisted === undefined) { + this.mutate(domainObject, 'persisted', domainObject.modified); + result = provider.create(domainObject); + } else { + this.mutate(domainObject, 'persisted', domainObject.modified); + result = provider.update(domainObject); + } + } + return result; }; /** @@ -276,5 +320,9 @@ define([ * @memberof module:openmct */ + function hasAlreadyBeenPersisted(domainObject) { + return domainObject.persisted !== undefined && + domainObject.persisted === domainObject.modified; + } return ObjectAPI; }); diff --git a/src/api/objects/ObjectAPISpec.js b/src/api/objects/ObjectAPISpec.js new file mode 100644 index 0000000000..38d648e100 --- /dev/null +++ b/src/api/objects/ObjectAPISpec.js @@ -0,0 +1,60 @@ +import ObjectAPI from './ObjectAPI.js'; + +describe("The Object API", () => { + let objectAPI; + let mockDomainObject; + const TEST_NAMESPACE = "test-namespace"; + const FIFTEEN_MINUTES = 15 * 60 * 1000; + + beforeEach(() => { + objectAPI = new ObjectAPI(); + mockDomainObject = { + identifier: { + namespace: TEST_NAMESPACE, + key: "test-key" + }, + name: "test object", + type: "test-type" + }; + }) + describe("The save function", () => { + it("Rejects if no provider available", () => { + let rejected = false; + return objectAPI.save(mockDomainObject) + .catch(() => rejected = true) + .then(() => expect(rejected).toBe(true)); + }); + describe("when a provider is available", () => { + let mockProvider; + beforeEach(() => { + mockProvider = jasmine.createSpyObj("mock provider", [ + "create", + "update" + ]); + objectAPI.addProvider(TEST_NAMESPACE, mockProvider); + }) + it("Calls 'create' on provider if object is new", () => { + objectAPI.save(mockDomainObject); + expect(mockProvider.create).toHaveBeenCalled(); + expect(mockProvider.update).not.toHaveBeenCalled(); + }); + it("Calls 'update' on provider if object is not new", () => { + mockDomainObject.persisted = Date.now() - FIFTEEN_MINUTES; + mockDomainObject.modified = Date.now(); + + objectAPI.save(mockDomainObject); + expect(mockProvider.create).not.toHaveBeenCalled(); + expect(mockProvider.update).toHaveBeenCalled(); + }); + + it("Does not persist if the object is unchanged", () => { + mockDomainObject.persisted = + mockDomainObject.modified = Date.now(); + + objectAPI.save(mockDomainObject); + expect(mockProvider.create).not.toHaveBeenCalled(); + expect(mockProvider.update).not.toHaveBeenCalled(); + }); + }); + }) +}); From 7221dc1ac6c4fdb77cd55a4245103956a90bf5cc Mon Sep 17 00:00:00 2001 From: Deep Tailor Date: Fri, 17 Jul 2020 16:48:14 -0700 Subject: [PATCH 12/19] make clear data indicator a configurable option (#3206) --- index.html | 5 ++++- src/plugins/clearData/plugin.js | 32 ++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/index.html b/index.html index 1034cd506e..3911020002 100644 --- a/index.html +++ b/index.html @@ -113,7 +113,10 @@ openmct.install(openmct.plugins.LADTable()); openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay'])); openmct.install(openmct.plugins.ObjectMigration()); - openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'])); + openmct.install(openmct.plugins.ClearData( + ['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'], + {indicator: true} + )); openmct.start(); diff --git a/src/plugins/clearData/plugin.js b/src/plugins/clearData/plugin.js index d4a6689cdc..ecc4d2ef8a 100644 --- a/src/plugins/clearData/plugin.js +++ b/src/plugins/clearData/plugin.js @@ -29,24 +29,28 @@ define([ ClearDataAction, Vue ) { - return function plugin(appliesToObjects) { + return function plugin(appliesToObjects, options = {indicator: true}) { + let installIndicator = options.indicator; + appliesToObjects = appliesToObjects || []; return function install(openmct) { - let component = new Vue ({ - provide: { - openmct - }, - components: { - GlobalClearIndicator: GlobaClearIndicator.default - }, - template: '' - }), - indicator = { - element: component.$mount().$el - }; + if (installIndicator) { + let component = new Vue ({ + provide: { + openmct + }, + components: { + GlobalClearIndicator: GlobaClearIndicator.default + }, + template: '' + }), + indicator = { + element: component.$mount().$el + }; - openmct.indicators.add(indicator); + openmct.indicators.add(indicator); + } openmct.contextMenu.registerAction(new ClearDataAction.default(openmct, appliesToObjects)); }; From f2d34d7c332ec8760a7f1eb834eec132c0f530cf Mon Sep 17 00:00:00 2001 From: Joshi Date: Mon, 20 Jul 2020 15:12:53 -0700 Subject: [PATCH 13/19] For the short term, removing use of ChromeHeadless and using FirefoxHeadless instead. (added npm dependency) Also increasing browserNoActivityTimeout to 90000 Resolves #3214 --- karma.conf.js | 5 +++-- package.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index dfc9b096c8..fe02334edc 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -23,7 +23,7 @@ /*global module,process*/ const devMode = process.env.NODE_ENV !== 'production'; -const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless']; +const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless']; const coverageEnabled = process.env.COVERAGE === 'true'; const reporters = ['progress', 'html']; @@ -95,6 +95,7 @@ module.exports = (config) => { stats: 'errors-only', logLevel: 'warn' }, - singleRun: true + singleRun: true, + browserNoActivityTimeout: 90000 }); } diff --git a/package.json b/package.json index 85bb0bbc3e..53defaa291 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "jsdoc": "^3.3.2", "karma": "^2.0.3", "karma-chrome-launcher": "^2.2.0", + "karma-firefox-launcher": "^1.3.0", "karma-cli": "^1.0.1", "karma-coverage": "^1.1.2", "karma-coverage-istanbul-reporter": "^2.1.1", From 97d80f57cc8554904374396e60be965c2b4c8574 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Tue, 21 Jul 2020 21:01:38 -0700 Subject: [PATCH 14/19] UI enhancements (#3217) * UI enhancements for #3176 - Large overlay now displays fullscreen; * UI enhancements for #3176 - Adding new ".is-in-small-container" CSS - VERY WIP! - TODO: fix table implementation; * UI fixes for NIRVSS client #170 - Hide table header filter inputs when table is in small container; * UI fixes for NIRVSS client #170 - Fixing legends and plot layout when small, and within a stacked plot; - Add new `hideLegendWhenSmall` property; - Remove 'hidden' from plot legend position options; - Reduced opacity of tabular headers in Espresso theme; - VERY, VERY WIP right now! * UI fixes for NIRVSS client #170 - Fixing legends and plot layout when small, and within a stacked plot; - Cleanups, indention, removed commented CSS; - Tightened up spacing in plot Y axis; * UI enhancements for #3176 - Move local controls for plots and imagery, prevent overlapping with view large button when in a hidden frame in a layout; - Finesse local control styling for increased legibility; - Move l-state-indicators to avoid overlap with repositioned local controls, finesse styling; * UI enhancements for #3176 - Tweak large overlay close button for better visual alignment; * UI enhancements for #3176 - Significant improvements to lines in Display Layouts; - Increased border-width for lines and boxes; - Code enhanced for proper handling of horizontal and vertical lines - but still isn't working properly; - Renamed box-view.scss to box-and-line-views.scss; - VERY WIP! * Fixed incorrect grid array reference * UI enhancements for #3176 - Fixed final issue with Display Layout line drawing object, thank you @deeptailor!; * UI enhancements for #3176 - Contrast enhancements and markup normalization for `c-object-label` elements in main view, Layout frames, Inspector and overlay; - Enhanced `l-overlay-large` layout; - Tightened up margins and spacing in plots; - Refined `is-paused` styling in Telemetry Tables; - Now hide Telemetry Tables 'Export Data' button if rows are selected, which use a separate export button; - Layout frames now hide button's text labels when small; - Layout frames spacing tightened up and improved; * UI enhancements for #3176 - Tweak Snow theme constants; * UI enhancements for #3176 - Fixed ObjectFrame getOverlayElement method, added a wrapper div around the viewed object to properly control resulting layout in the overlay; - Simplified preview CSS to remove background, border and padding; - Layout tweaks to add space between scrollbar and thumbs in Imagery view; - Removed dev "-info" element in LineView.vue; * UI enhancements for #3176 - Improved styling for 'edit lock' button; * UI enhancements for #3176 - Show Display Layout frame "-move" bar on hover, rather than select, to make it easier to select items with hidden frames, and only show -move bar's drag grippy when that frame is selected; - `pointer-events: none` applied to table's body and plot's plot areas when placed in a Layout and being edited, prevents distracting interactions (plot zoom/pan, table row selection) when selecting and moving elements in a Layout; - Refined hover styles for c-button to use $filterHov, simplified and normalized hover styling; - Converted a number of old `` tags to `` to normalize styling and use the appropriate control; - Edit lock button is now colored when locked; * Fix linting issue * Minor tweaks - Tweaked control positioning; Co-authored-by: Shefali Joshi --- .../commonUI/dialog/res/templates/dialog.html | 8 +- .../dialog/res/templates/overlay-options.html | 4 +- platform/search/res/templates/search.html | 14 +-- .../components/overlay-component.scss | 34 +++++- .../displayLayout/components/LayoutFrame.vue | 10 +- .../displayLayout/components/LineView.vue | 85 +++++++++----- .../components/box-and-line-views.scss | 55 +++++++++ .../displayLayout/components/box-view.scss | 8 -- .../components/layout-frame.scss | 15 ++- .../imagery/components/ImageryViewLayout.vue | 4 +- .../components/imagery-view-layout.scss | 3 +- src/plugins/plot/res/templates/mct-plot.html | 36 +++--- .../res/templates/plot-options-browse.html | 5 + .../plot/res/templates/plot-options-edit.html | 6 +- .../plot/src/configuration/LegendModel.js | 1 + .../src/inspector/PlotLegendFormController.js | 5 + .../telemetryTable/components/table.scss | 22 +++- .../telemetryTable/components/table.vue | 7 +- src/styles/_constants-espresso.scss | 14 ++- src/styles/_constants-maelstrom.scss | 10 +- src/styles/_constants-snow.scss | 8 +- src/styles/_constants.scss | 7 +- src/styles/_controls.scss | 5 - src/styles/_global.scss | 4 - src/styles/_legacy-plots.scss | 106 +++++++++++++----- src/styles/_mixins.scss | 16 +-- src/styles/_table.scss | 18 ++- src/styles/vue-styles.scss | 2 +- src/ui/components/ObjectFrame.vue | 5 +- src/ui/components/object-frame.scss | 46 ++++---- src/ui/components/object-label.scss | 1 + src/ui/inspector/ObjectName.vue | 17 +-- src/ui/inspector/inspector.scss | 13 ++- src/ui/layout/BrowseBar.vue | 2 +- src/ui/layout/layout.scss | 11 ++ src/ui/preview/preview-header.vue | 10 +- src/ui/preview/preview.scss | 4 +- 37 files changed, 429 insertions(+), 192 deletions(-) create mode 100644 src/plugins/displayLayout/components/box-and-line-views.scss delete mode 100644 src/plugins/displayLayout/components/box-view.scss diff --git a/platform/commonUI/dialog/res/templates/dialog.html b/platform/commonUI/dialog/res/templates/dialog.html index 78b852c968..6c6b3d44da 100644 --- a/platform/commonUI/dialog/res/templates/dialog.html +++ b/platform/commonUI/dialog/res/templates/dialog.html @@ -31,13 +31,13 @@
diff --git a/platform/commonUI/dialog/res/templates/overlay-options.html b/platform/commonUI/dialog/res/templates/overlay-options.html index 40bf8d9755..d83d5b7302 100644 --- a/platform/commonUI/dialog/res/templates/overlay-options.html +++ b/platform/commonUI/dialog/res/templates/overlay-options.html @@ -31,13 +31,13 @@
diff --git a/platform/search/res/templates/search.html b/platform/search/res/templates/search.html index 726f04fdd6..d0bfcfcf92 100644 --- a/platform/search/res/templates/search.html +++ b/platform/search/res/templates/search.html @@ -29,9 +29,9 @@ type="text" tabindex="10000" ng-model="ngModel.input" ng-keyup="controller.search()"/> - + ng-click="ngModel.input = ''; controller.search()">
- - Cancel + Cancel
- Filtered by: {{ ngModel.filtersString }} + Filtered by: {{ ngModel.filtersString }}
@@ -72,7 +72,7 @@ ng-model="ngModel" class="l-flex-row flex-elem grows"> - More Results +
diff --git a/src/api/overlays/components/overlay-component.scss b/src/api/overlays/components/overlay-component.scss index 14de7b0c4a..c30ffa5191 100644 --- a/src/api/overlays/components/overlay-component.scss +++ b/src/api/overlays/components/overlay-component.scss @@ -36,6 +36,7 @@ font-size: 1.25em; position: absolute; top: $p; right: $p; + z-index: 99; } &__contents { @@ -43,7 +44,7 @@ display: flex; flex-direction: column; outline: none; - overflow: hidden; + overflow: auto; } &__top-bar { @@ -87,6 +88,10 @@ .c-click-icon { filter: $overlayBrightnessAdjust; } + + .c-object-label__name { + filter: $objectLabelNameFilter; + } } body.desktop { @@ -100,7 +105,6 @@ body.desktop { } // Overlay types, styling for desktop. Appended to .l-overlay-wrapper element. - .l-overlay-large, .l-overlay-small, .l-overlay-fit { .c-overlay__outer { @@ -118,8 +122,28 @@ body.desktop { .l-overlay-large { // Default - .c-overlay__outer { - @include overlaySizing($overlayOuterMarginLg); + $pad: $interiorMarginLg; + $tbPad: floor($pad * 0.8); + $lrPad: $pad; + .c-overlay { + &__blocker { + display: none; + } + + &__outer { + @include overlaySizing($overlayOuterMarginFullscreen); + padding: $tbPad $lrPad; + } + + &__close-button { + top: $pad; + right: $interiorMarginSm; + } + } + + .l-browse-bar { + margin-right: $lrPad + $pad; // Don't cover close button + margin-bottom: $interiorMargin; } } @@ -139,4 +163,4 @@ body.desktop { min-width: 20%; } } -} \ No newline at end of file +} diff --git a/src/plugins/displayLayout/components/LayoutFrame.vue b/src/plugins/displayLayout/components/LayoutFrame.vue index 330e6025ee..70bc9bf653 100644 --- a/src/plugins/displayLayout/components/LayoutFrame.vue +++ b/src/plugins/displayLayout/components/LayoutFrame.vue @@ -25,7 +25,8 @@ class="l-layout__frame c-frame" :class="{ 'no-frame': !item.hasFrame, - 'u-inspectable': inspectable + 'u-inspectable': inspectable, + 'is-in-small-container': size.width < 600 || size.height < 600 }" :style="style" > @@ -61,6 +62,13 @@ export default { } }, computed: { + size() { + let {width, height} = this.item; + return { + width: (this.gridSize[0] * width), + height: (this.gridSize[1] * height) + }; + }, style() { let {x, y, width, height} = this.item; return { diff --git a/src/plugins/displayLayout/components/LineView.vue b/src/plugins/displayLayout/components/LineView.vue index fb19a70049..dc6d9bf934 100644 --- a/src/plugins/displayLayout/components/LineView.vue +++ b/src/plugins/displayLayout/components/LineView.vue @@ -22,7 +22,7 @@