From 546cde56a8f410d0178ede21e6cc25a85280d4c3 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 15 Apr 2016 08:32:34 -0700 Subject: [PATCH 01/24] [Timeline] Expose internal resource utilization ...to allow this to be exported for CSV, #751 --- .../timeline/src/capabilities/UtilizationCapability.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/platform/features/timeline/src/capabilities/UtilizationCapability.js b/platform/features/timeline/src/capabilities/UtilizationCapability.js index 140f527c0d..33a7e4f793 100644 --- a/platform/features/timeline/src/capabilities/UtilizationCapability.js +++ b/platform/features/timeline/src/capabilities/UtilizationCapability.js @@ -195,6 +195,13 @@ define( * @returns {Promise.} a promise for resource identifiers */ resources: promiseResourceKeys, + /** + * Get the resource utilization associated with this object + * directly, not including any resource utilization associated + * with contained objects. + * @returns {Promise.} + */ + internal: promiseInternalUtilization, /** * Get the resource utilization associated with this * object. Results are not sorted. This requires looking From f683ca44a220359989c1c1841a3b7f66d7280fbb Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 15 Apr 2016 08:45:42 -0700 Subject: [PATCH 02/24] [Timeline] Read resource utilizations during CSV export --- .../src/actions/TimelineColumnizer.js | 19 +++++- .../timeline/src/actions/UtilizationColumn.js | 58 +++++++++++++++++++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 platform/features/timeline/src/actions/UtilizationColumn.js diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index 3069bd8b96..02d3ad6b69 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -68,11 +68,12 @@ define([ * @constructor * @memberof {platform/features/timeline} */ - function TimelineColumnizer(domainObjects) { + function TimelineColumnizer(domainObjects, resourceMap) { var maxComposition = 0, maxRelationships = 0, columnNames = {}, columns = [], + costKeys = [], foundTimespan = false, i; @@ -84,6 +85,14 @@ define([ } } + function addCostProperties(costCapability) { + costCapability.resources().forEach(function (key) { + if (costKeys.indexOf(key) === -1) { + costKeys.push(key); + } + }); + } + columns.push(new IdColumn()); domainObjects.forEach(function (domainObject) { @@ -105,6 +114,10 @@ define([ foundTimespan = true; } + if (domainObject.hasCapability('cost')) { + addCostProperties(domainObject.getCapability('cost')); + } + if (metadataProperties) { metadataProperties.forEach(addMetadataProperty); } @@ -115,6 +128,10 @@ define([ columns.push(new TimespanColumn(false)); } + costKeys.forEach(function (key) { + columns.push(new UtilizationColumn(resourceMap[key])); + }); + for (i = 0; i < maxComposition; i += 1) { columns.push(new CompositionColumn(i)); } diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js new file mode 100644 index 0000000000..f2c8a56544 --- /dev/null +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -0,0 +1,58 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2009-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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. + *****************************************************************************/ +/*global define*/ + +define([], function () { + "use strict"; + + /** + * A column showing utilization costs associated with activities. + * @constructor + * @param {string} key the key for the particular cost + * @implements {platform/features/timeline.TimelineCSVColumn} + */ + function UtilizationColumn(resource) { + this.resource = resource; + } + + UtilizationColumn.prototype.name = function () { + return this.resource.name; + }; + + UtilizationColumn.prototype.value = function (domainObject) { + var resource = this.resource; + + function getUtilizationValue(utilizations) { + utilizations = utilizations.filter(function (utilization) { + return key === resource.key; + }); + return utilizations.length === 1 ? utilizations[0].value : ""; + } + + return !domainObject.hasCapability('utilization') ? + "" : + domainObject.getCapability('utilization').internal() + .then(getUtilizationValue); + }; + + return UtilizationColumn; +}); From f16a107105415cb470a9ba3a10515483e3d1655d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 15 Apr 2016 08:51:22 -0700 Subject: [PATCH 03/24] [Timeline] Inject resources into CSV action --- platform/features/timeline/bundle.js | 6 +++++- .../timeline/src/actions/ExportTimelineAsCSVAction.js | 11 +++++++++-- .../timeline/src/actions/ExportTimelineAsCSVTask.js | 6 ++++-- .../timeline/src/actions/TimelineColumnizer.js | 11 +++-------- 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index 8e2a40ed7d..27420fd032 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -93,7 +93,11 @@ define([ "name": "Export Timeline as CSV", "category": "contextual", "implementation": ExportTimelineAsCSVAction, - "depends": [ "exportService", "notificationService" ] + "depends": [ + "exportService", + "notificationService", + "resources[]" + ] } ], "constants": [ diff --git a/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js b/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js index 387c0839a0..e50b9369db 100644 --- a/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js +++ b/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js @@ -29,14 +29,21 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) { * * @param exportService the service used to perform the CSV export * @param notificationService the service used to show notifications + * @param {Array} resources an array of `resources` extensions * @param context the Action's context * @implements {Action} * @constructor * @memberof {platform/features/timeline} */ - function ExportTimelineAsCSVAction(exportService, notificationService, context) { + function ExportTimelineAsCSVAction( + exportService, + notificationService, + resources, + context + ) { this.task = new ExportTimelineAsCSVTask( exportService, + resources, context.domainObject ); this.notificationService = notificationService; @@ -67,4 +74,4 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) { }; return ExportTimelineAsCSVAction; -}); \ No newline at end of file +}); diff --git a/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js b/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js index 253db5c8b9..5979347d3c 100644 --- a/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js +++ b/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js @@ -37,11 +37,13 @@ define([ * @constructor * @memberof {platform/features/timeline} * @param exportService the service used to export as CSV + * @param resources the `resources` extension category * @param {DomainObject} domainObject the timeline being exported */ - function ExportTimelineAsCSVTask(exportService, domainObject) { + function ExportTimelineAsCSVTask(exportService, resources, domainObject) { this.domainObject = domainObject; this.exportService = exportService; + this.resources = resources; } /** @@ -54,7 +56,7 @@ define([ var exportService = this.exportService; function doExport(objects) { - var exporter = new TimelineColumnizer(objects), + var exporter = new TimelineColumnizer(objects, this.resources), options = { headers: exporter.headers() }; return exporter.rows().then(function (rows) { return exportService.exportCSV(rows, options); diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index 02d3ad6b69..035496edc6 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -68,12 +68,11 @@ define([ * @constructor * @memberof {platform/features/timeline} */ - function TimelineColumnizer(domainObjects, resourceMap) { + function TimelineColumnizer(domainObjects, resources) { var maxComposition = 0, maxRelationships = 0, columnNames = {}, columns = [], - costKeys = [], foundTimespan = false, i; @@ -114,10 +113,6 @@ define([ foundTimespan = true; } - if (domainObject.hasCapability('cost')) { - addCostProperties(domainObject.getCapability('cost')); - } - if (metadataProperties) { metadataProperties.forEach(addMetadataProperty); } @@ -128,8 +123,8 @@ define([ columns.push(new TimespanColumn(false)); } - costKeys.forEach(function (key) { - columns.push(new UtilizationColumn(resourceMap[key])); + resources.forEach(function (resource) { + columns.push(new UtilizationColumn(resource)); }); for (i = 0; i < maxComposition; i += 1) { From 1ced47fc2c55f14b2fd338095b34c4dd10df9900 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 19 May 2016 16:26:30 -0700 Subject: [PATCH 04/24] [Navigation] Prevent navigation to orphan objects This is particularly useful when a persistence failure has caused a created object not to be added to its parent container. #765 --- platform/commonUI/browse/bundle.js | 10 + .../src/navigation/OrphanNavigationHandler.js | 75 ++++++++ .../navigation/OrphanNavigationHandlerSpec.js | 180 ++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js create mode 100644 platform/commonUI/browse/test/navigation/OrphanNavigationHandlerSpec.js diff --git a/platform/commonUI/browse/bundle.js b/platform/commonUI/browse/bundle.js index 73b3f44de7..b7cf2dca71 100644 --- a/platform/commonUI/browse/bundle.js +++ b/platform/commonUI/browse/bundle.js @@ -30,6 +30,7 @@ define([ "./src/navigation/NavigationService", "./src/creation/CreationPolicy", "./src/navigation/NavigateAction", + "./src/navigation/OrphanNavigationHandler", "./src/windowing/NewTabAction", "./src/windowing/FullscreenAction", "./src/creation/CreateActionProvider", @@ -59,6 +60,7 @@ define([ NavigationService, CreationPolicy, NavigateAction, + OrphanNavigationHandler, NewTabAction, FullscreenAction, CreateActionProvider, @@ -346,6 +348,14 @@ define([ "$rootScope", "$document" ] + }, + { + "implementation": OrphanNavigationHandler, + "depends": [ + "throttle", + "topic", + "navigationService" + ] } ], "licenses": [ diff --git a/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js b/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js new file mode 100644 index 0000000000..00b3182e42 --- /dev/null +++ b/platform/commonUI/browse/src/navigation/OrphanNavigationHandler.js @@ -0,0 +1,75 @@ +/***************************************************************************** + * Open MCT Web, Copyright (c) 2014-2015, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT Web 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 Web 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([], function () { + + /** + * Navigates away from orphan objects whenever they are detected. + * + * An orphan object is an object whose apparent parent does not + * actually contain it. This may occur in certain circumstances, such + * as when persistence succeeds for a newly-created object but fails + * for its parent. + * + * @param throttle the `throttle` service + * @param topic the `topic` service + * @param navigationService the `navigationService` + * @constructor + */ + function OrphanNavigationHandler(throttle, topic, navigationService) { + var throttledCheckNavigation; + + function getParent(domainObject) { + var context = domainObject.getCapability('context'); + return context.getParent(); + } + + function isOrphan(domainObject) { + var parent = getParent(domainObject), + composition = parent.getModel().composition, + id = domainObject.getId(); + return !composition || (composition.indexOf(id) === -1); + } + + function navigateToParent(domainObject) { + var parent = getParent(domainObject); + return parent.getCapability('action').perform('navigate'); + } + + function checkNavigation() { + var navigatedObject = navigationService.getNavigation(); + if (navigatedObject.hasCapability('context') && + isOrphan(navigatedObject)) { + if (!navigatedObject.getCapability('editor').isEditContextRoot()) { + navigateToParent(navigatedObject); + } + } + } + + throttledCheckNavigation = throttle(checkNavigation); + + navigationService.addListener(throttledCheckNavigation); + topic('mutation').listen(throttledCheckNavigation); + } + + return OrphanNavigationHandler; +}); diff --git a/platform/commonUI/browse/test/navigation/OrphanNavigationHandlerSpec.js b/platform/commonUI/browse/test/navigation/OrphanNavigationHandlerSpec.js new file mode 100644 index 0000000000..4f71feedbd --- /dev/null +++ b/platform/commonUI/browse/test/navigation/OrphanNavigationHandlerSpec.js @@ -0,0 +1,180 @@ +/***************************************************************************** +* Open MCT Web, Copyright (c) 2014-2015, United States Government +* as represented by the Administrator of the National Aeronautics and Space +* Administration. All rights reserved. +* +* Open MCT Web 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 Web 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/navigation/OrphanNavigationHandler' +], function (OrphanNavigationHandler) { + describe("OrphanNavigationHandler", function () { + var mockTopic, + mockThrottle, + mockMutationTopic, + mockNavigationService, + mockDomainObject, + mockParentObject, + mockContext, + mockActionCapability, + mockEditor, + testParentModel, + testId, + mockThrottledFns; + + beforeEach(function () { + testId = 'some-identifier'; + + mockThrottledFns = []; + testParentModel = {}; + + mockTopic = jasmine.createSpy('topic'); + mockThrottle = jasmine.createSpy('throttle'); + mockNavigationService = jasmine.createSpyObj('navigationService', [ + 'getNavigation', + 'addListener' + ]); + mockMutationTopic = jasmine.createSpyObj('mutationTopic', [ + 'listen' + ]); + mockDomainObject = jasmine.createSpyObj('domainObject', [ + 'getId', + 'getCapability', + 'getModel', + 'hasCapability' + ]); + mockParentObject = jasmine.createSpyObj('domainObject', [ + 'getId', + 'getCapability', + 'getModel', + 'hasCapability' + ]); + mockContext = jasmine.createSpyObj('context', ['getParent']); + mockActionCapability = jasmine.createSpyObj('action', ['perform']); + mockEditor = jasmine.createSpyObj('editor', ['isEditContextRoot']); + + mockThrottle.andCallFake(function (fn) { + var mockThrottledFn = + jasmine.createSpy('throttled-' + mockThrottledFns.length); + mockThrottledFn.andCallFake(fn); + mockThrottledFns.push(mockThrottledFn); + return mockThrottledFn; + }); + mockTopic.andCallFake(function (k) { + return k === 'mutation' && mockMutationTopic; + }); + mockDomainObject.getId.andReturn(testId); + mockDomainObject.getCapability.andCallFake(function (c) { + return { + context: mockContext, + editor: mockEditor + }[c]; + }); + mockDomainObject.hasCapability.andCallFake(function (c) { + return !!mockDomainObject.getCapability(c); + }); + mockParentObject.getModel.andReturn(testParentModel); + mockParentObject.getCapability.andCallFake(function (c) { + return { + action: mockActionCapability + }[c]; + }); + mockContext.getParent.andReturn(mockParentObject); + mockNavigationService.getNavigation.andReturn(mockDomainObject); + mockEditor.isEditContextRoot.andReturn(false); + + return new OrphanNavigationHandler( + mockThrottle, + mockTopic, + mockNavigationService + ); + }); + + + it("listens for mutation with a throttled function", function () { + expect(mockMutationTopic.listen) + .toHaveBeenCalledWith(jasmine.any(Function)); + expect(mockThrottledFns.indexOf( + mockMutationTopic.listen.mostRecentCall.args[0] + )).not.toEqual(-1); + }); + + it("listens for navigation changes with a throttled function", function () { + expect(mockNavigationService.addListener) + .toHaveBeenCalledWith(jasmine.any(Function)); + expect(mockThrottledFns.indexOf( + mockNavigationService.addListener.mostRecentCall.args[0] + )).not.toEqual(-1); + }); + + [false, true].forEach(function (isOrphan) { + var prefix = isOrphan ? "" : "non-"; + describe("for " + prefix + "orphan objects", function () { + beforeEach(function () { + testParentModel.composition = isOrphan ? [] : [testId]; + }); + + [false, true].forEach(function (isEditRoot) { + var caseName = isEditRoot ? + "that are being edited" : "that are not being edited"; + + function itNavigatesAsExpected() { + if (isOrphan && !isEditRoot) { + it("navigates to the parent", function () { + expect(mockActionCapability.perform) + .toHaveBeenCalledWith('navigate'); + }); + } else { + it("does nothing", function () { + expect(mockActionCapability.perform) + .not.toHaveBeenCalled(); + }); + } + } + + describe(caseName, function () { + beforeEach(function () { + mockEditor.isEditContextRoot.andReturn(isEditRoot); + }); + + describe("when navigation changes", function () { + beforeEach(function () { + mockNavigationService.addListener.mostRecentCall + .args[0](mockDomainObject); + }); + + itNavigatesAsExpected(); + }); + + describe("when mutation occurs", function () { + beforeEach(function () { + mockMutationTopic.listen.mostRecentCall + .args[0](mockParentObject); + }); + + itNavigatesAsExpected(); + }); + + }); + }); + }); + }); + + }); +}); + From ed519d89d70568f608eb41f12d3de2097921673d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 10:35:29 -0700 Subject: [PATCH 05/24] [Timeline] Log errors during CSV export #751 --- platform/features/timeline/bundle.js | 1 + .../timeline/src/actions/ExportTimelineAsCSVAction.js | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index e44b27c589..4663a37fae 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -92,6 +92,7 @@ define([ "category": "contextual", "implementation": ExportTimelineAsCSVAction, "depends": [ + "$log", "exportService", "notificationService", "resources[]" diff --git a/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js b/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js index 57ac17c8a0..5b0e007e23 100644 --- a/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js +++ b/platform/features/timeline/src/actions/ExportTimelineAsCSVAction.js @@ -34,11 +34,13 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) { * @memberof {platform/features/timeline} */ function ExportTimelineAsCSVAction( + $log, exportService, notificationService, resources, context ) { + this.$log = $log; this.task = new ExportTimelineAsCSVTask( exportService, resources, @@ -52,13 +54,15 @@ define(["./ExportTimelineAsCSVTask"], function (ExportTimelineAsCSVTask) { notification = notificationService.notify({ title: "Exporting CSV", unknownProgress: true - }); + }), + $log = this.$log; return this.task.run() .then(function () { notification.dismiss(); }) - .catch(function () { + .catch(function (err) { + $log.warn(err); notification.dismiss(); notificationService.error("Error exporting CSV"); }); From 81624291061c43b13326b0da6156e2588be90482 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 10:37:01 -0700 Subject: [PATCH 06/24] [Timeline] Pass in resources extensions --- .../features/timeline/src/actions/ExportTimelineAsCSVTask.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js b/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js index 1e9be7d97a..d026edff3a 100644 --- a/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js +++ b/platform/features/timeline/src/actions/ExportTimelineAsCSVTask.js @@ -52,9 +52,10 @@ define([ */ ExportTimelineAsCSVTask.prototype.run = function () { var exportService = this.exportService; + var resources = this.resources; function doExport(objects) { - var exporter = new TimelineColumnizer(objects, this.resources), + var exporter = new TimelineColumnizer(objects, resources), options = { headers: exporter.headers() }; return exporter.rows().then(function (rows) { return exportService.exportCSV(rows, options); From 0cc2ba75958c8824858136c2f3078e70b453cc19 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 10:38:00 -0700 Subject: [PATCH 07/24] [Timeline] Import UtilizationColumn --- .../features/timeline/src/actions/TimelineColumnizer.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index 5468add401..bfbd5e34c2 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -25,13 +25,15 @@ define([ "./ModeColumn", "./CompositionColumn", "./MetadataColumn", - "./TimespanColumn" + "./TimespanColumn", + "./UtilizationColumn" ], function ( IdColumn, ModeColumn, CompositionColumn, MetadataColumn, - TimespanColumn + TimespanColumn, + UtilizationColumn ) { /** From bb4f1ce7cd87781198705362c0a4c1ed3dcb6fd9 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 10:52:25 -0700 Subject: [PATCH 08/24] [Timeline] Include utilization columns --- platform/features/timeline/bundle.js | 3 ++- .../timeline/src/actions/UtilizationColumn.js | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index 4663a37fae..b8754f4916 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -557,7 +557,8 @@ define([ { "key": "comms", "name": "Comms", - "units": "Kbps" + "units": "Kbps", + "foo": "Kb" }, { "key": "battery", diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js index f2c8a56544..e9e88a5896 100644 --- a/platform/features/timeline/src/actions/UtilizationColumn.js +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -41,11 +41,23 @@ define([], function () { UtilizationColumn.prototype.value = function (domainObject) { var resource = this.resource; + function getCost(utilization) { + var seconds = (utilization.end - utilization.start) / 1000; + return seconds * utilization.value; + } + function getUtilizationValue(utilizations) { utilizations = utilizations.filter(function (utilization) { - return key === resource.key; + return utilization.key === resource.key; }); - return utilizations.length === 1 ? utilizations[0].value : ""; + + if (utilizations.length === 0) { + return ""; + } + + return utilizations.map(getCost).reduce(function (a, b) { + return a + b; + }, 0); } return !domainObject.hasCapability('utilization') ? From 463f7ccf65024ea0c3048cdb2b8d8368132ca7a3 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:07:35 -0700 Subject: [PATCH 09/24] [Timeline] Use indexes instead of UUIDs --- .../timeline/src/actions/CompositionColumn.js | 7 +++++-- platform/features/timeline/src/actions/IdColumn.js | 7 ++++--- platform/features/timeline/src/actions/ModeColumn.js | 8 +++++--- .../timeline/src/actions/TimelineColumnizer.js | 12 +++++++++--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/platform/features/timeline/src/actions/CompositionColumn.js b/platform/features/timeline/src/actions/CompositionColumn.js index f9bede9983..3fff0bda37 100644 --- a/platform/features/timeline/src/actions/CompositionColumn.js +++ b/platform/features/timeline/src/actions/CompositionColumn.js @@ -30,8 +30,9 @@ define([], function () { * @constructor * @implements {platform/features/timeline.TimelineCSVColumn} */ - function CompositionColumn(index) { + function CompositionColumn(index, idMap) { this.index = index; + this.idMap = idMap; } CompositionColumn.prototype.name = function () { @@ -41,7 +42,9 @@ define([], function () { CompositionColumn.prototype.value = function (domainObject) { var model = domainObject.getModel(), composition = model.composition || []; - return (composition[this.index]) || ""; + + return composition.length > this.index ? + this.idMap[composition[this.index]] : ""; }; return CompositionColumn; diff --git a/platform/features/timeline/src/actions/IdColumn.js b/platform/features/timeline/src/actions/IdColumn.js index 38c8b9264e..b6ff15fe6c 100644 --- a/platform/features/timeline/src/actions/IdColumn.js +++ b/platform/features/timeline/src/actions/IdColumn.js @@ -27,15 +27,16 @@ define([], function () { * @constructor * @implements {platform/features/timeline.TimelineCSVColumn} */ - function IdColumn() { + function IdColumn(idMap) { + this.idMap = idMap; } IdColumn.prototype.name = function () { - return "Identifier"; + return "Index"; }; IdColumn.prototype.value = function (domainObject) { - return domainObject.getId(); + return this.idMap[domainObject.getId()]; }; return IdColumn; diff --git a/platform/features/timeline/src/actions/ModeColumn.js b/platform/features/timeline/src/actions/ModeColumn.js index fe2063566d..26b307cbd0 100644 --- a/platform/features/timeline/src/actions/ModeColumn.js +++ b/platform/features/timeline/src/actions/ModeColumn.js @@ -29,8 +29,9 @@ define([], function () { * element associated with this column * @implements {platform/features/timeline.TimelineCSVColumn} */ - function ModeColumn(index) { + function ModeColumn(index, idMap) { this.index = index; + this.idMap = idMap; } ModeColumn.prototype.name = function () { @@ -39,8 +40,9 @@ define([], function () { ModeColumn.prototype.value = function (domainObject) { var model = domainObject.getModel(), - composition = (model.relationships || {}).modes || []; - return (composition[this.index]) || ""; + modes = (model.relationships || {}).modes || []; + return modes.length > this.index ? + this.idMap[modes[this.index]] : ""; }; return ModeColumn; diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index bfbd5e34c2..fb0b80a7f7 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -74,6 +74,7 @@ define([ columnNames = {}, columns = [], foundTimespan = false, + idMap, i; function addMetadataProperty(property) { @@ -92,7 +93,12 @@ define([ }); } - columns.push(new IdColumn()); + idMap = domainObjects.reduce(function (map, domainObject, index) { + map[domainObject.getId()] = index + 1; + return map; + }, {}); + + columns.push(new IdColumn(idMap)); domainObjects.forEach(function (domainObject) { var model = domainObject.getModel(), @@ -128,11 +134,11 @@ define([ }); for (i = 0; i < maxComposition; i += 1) { - columns.push(new CompositionColumn(i)); + columns.push(new CompositionColumn(i, idMap)); } for (i = 0; i < maxRelationships; i += 1) { - columns.push(new ModeColumn(i)); + columns.push(new ModeColumn(i, idMap)); } this.domainObjects = domainObjects; From 23c71b7218a8c9392bda20c595b4b2e17fc7947d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:12:11 -0700 Subject: [PATCH 10/24] [Timeline] Include units for utilizations --- platform/features/timeline/bundle.js | 3 +-- .../features/timeline/src/actions/UtilizationColumn.js | 10 +++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/platform/features/timeline/bundle.js b/platform/features/timeline/bundle.js index b8754f4916..4663a37fae 100644 --- a/platform/features/timeline/bundle.js +++ b/platform/features/timeline/bundle.js @@ -557,8 +557,7 @@ define([ { "key": "comms", "name": "Comms", - "units": "Kbps", - "foo": "Kb" + "units": "Kbps" }, { "key": "battery", diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js index e9e88a5896..7da7b6c890 100644 --- a/platform/features/timeline/src/actions/UtilizationColumn.js +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -34,6 +34,14 @@ define([], function () { this.resource = resource; } + UtilizationColumn.prototype.getUnits = function () { + var instantaneousUnits = this.resource.units; + return { + "Kbps": "Kb", + "Watts": "joules", + }[instantaneousUnits] || "unknown units"; + }; + UtilizationColumn.prototype.name = function () { return this.resource.name; }; @@ -57,7 +65,7 @@ define([], function () { return utilizations.map(getCost).reduce(function (a, b) { return a + b; - }, 0); + }, 0) + " (" + this.getUnits() + ")"; } return !domainObject.hasCapability('utilization') ? From a3bcaea7f95efc3a1f1305e994a8d24bfe32c468 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:21:58 -0700 Subject: [PATCH 11/24] [Timeline] Show units in utilization headers --- .../timeline/src/actions/UtilizationColumn.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js index 7da7b6c890..e87794237b 100644 --- a/platform/features/timeline/src/actions/UtilizationColumn.js +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -34,16 +34,13 @@ define([], function () { this.resource = resource; } - UtilizationColumn.prototype.getUnits = function () { - var instantaneousUnits = this.resource.units; - return { - "Kbps": "Kb", - "Watts": "joules", - }[instantaneousUnits] || "unknown units"; - }; - UtilizationColumn.prototype.name = function () { - return this.resource.name; + var units = { + "Kbps": "Kb", + "watts": "watt-seconds" + }[this.resource.units] || "unknown units"; + + return this.resource.name + " (" + units + ")"; }; UtilizationColumn.prototype.value = function (domainObject) { @@ -65,7 +62,7 @@ define([], function () { return utilizations.map(getCost).reduce(function (a, b) { return a + b; - }, 0) + " (" + this.getUnits() + ")"; + }, 0); } return !domainObject.hasCapability('utilization') ? From d7f566088f22d4e5e67e4099d45adec756c8e716 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:25:02 -0700 Subject: [PATCH 12/24] [Timeline] Update spec to include logging --- .../actions/ExportTimelineAsCSVActionSpec.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/platform/features/timeline/test/actions/ExportTimelineAsCSVActionSpec.js b/platform/features/timeline/test/actions/ExportTimelineAsCSVActionSpec.js index e0f09c3ae6..e31f25b074 100644 --- a/platform/features/timeline/test/actions/ExportTimelineAsCSVActionSpec.js +++ b/platform/features/timeline/test/actions/ExportTimelineAsCSVActionSpec.js @@ -24,7 +24,8 @@ define( ['../../src/actions/ExportTimelineAsCSVAction'], function (ExportTimelineAsCSVAction) { describe("ExportTimelineAsCSVAction", function () { - var mockExportService, + var mockLog, + mockExportService, mockNotificationService, mockNotification, mockDomainObject, @@ -39,6 +40,13 @@ define( ['getId', 'getModel', 'getCapability', 'hasCapability'] ); mockType = jasmine.createSpyObj('type', ['instanceOf']); + + mockLog = jasmine.createSpyObj('$log', [ + 'warn', + 'error', + 'info', + 'debug' + ]); mockExportService = jasmine.createSpyObj( 'exportService', ['exportCSV'] @@ -63,8 +71,10 @@ define( testContext = { domainObject: mockDomainObject }; action = new ExportTimelineAsCSVAction( + mockLog, mockExportService, mockNotificationService, + [], testContext ); }); @@ -129,8 +139,11 @@ define( }); describe("and an error occurs", function () { + var testError; + beforeEach(function () { - testPromise.reject(); + testError = { someProperty: "some value" }; + testPromise.reject(testError); waitsFor(function () { return mockCallback.calls.length > 0; }); @@ -145,6 +158,10 @@ define( expect(mockNotificationService.error) .toHaveBeenCalledWith(jasmine.any(String)); }); + + it("logs the root cause", function () { + expect(mockLog.warn).toHaveBeenCalledWith(testError); + }); }); }); }); From 80f5cb756d017f68165043cf31a88ef623ab5144 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:25:58 -0700 Subject: [PATCH 13/24] [Timeline] Account for new argument in spec --- .../timeline/test/actions/ExportTimelineAsCSVTaskSpec.js | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/features/timeline/test/actions/ExportTimelineAsCSVTaskSpec.js b/platform/features/timeline/test/actions/ExportTimelineAsCSVTaskSpec.js index 0330e86397..4deab99801 100644 --- a/platform/features/timeline/test/actions/ExportTimelineAsCSVTaskSpec.js +++ b/platform/features/timeline/test/actions/ExportTimelineAsCSVTaskSpec.js @@ -52,6 +52,7 @@ define( task = new ExportTimelineAsCSVTask( mockExportService, + [], mockDomainObject ); }); From ba0d9a186b2c38cf89c29a38a61130d2fcd18a9e Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:26:47 -0700 Subject: [PATCH 14/24] [Timeline] Account for new argument in spec --- .../features/timeline/test/actions/TimelineColumnizerSpec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/features/timeline/test/actions/TimelineColumnizerSpec.js b/platform/features/timeline/test/actions/TimelineColumnizerSpec.js index d29bb14278..3c9b3de7e6 100644 --- a/platform/features/timeline/test/actions/TimelineColumnizerSpec.js +++ b/platform/features/timeline/test/actions/TimelineColumnizerSpec.js @@ -75,7 +75,7 @@ define( return c === 'metadata' && testMetadata; }); - exporter = new TimelineColumnizer(mockDomainObjects); + exporter = new TimelineColumnizer(mockDomainObjects, []); }); describe("rows", function () { From 73b922facfddf0070ed8e35f24c87df029e3cae7 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:32:44 -0700 Subject: [PATCH 15/24] [Timeline] Update specs for indexes instead of ids --- .../test/actions/CompositionColumnSpec.js | 17 +++++++++++------ .../timeline/test/actions/IdColumnSpec.js | 10 ++++++---- .../timeline/test/actions/ModeColumnSpec.js | 15 +++++++++++---- .../test/actions/TimelineColumnizerSpec.js | 7 ------- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/platform/features/timeline/test/actions/CompositionColumnSpec.js b/platform/features/timeline/test/actions/CompositionColumnSpec.js index 8cf566a080..df52d08db5 100644 --- a/platform/features/timeline/test/actions/CompositionColumnSpec.js +++ b/platform/features/timeline/test/actions/CompositionColumnSpec.js @@ -23,13 +23,20 @@ define( ['../../src/actions/CompositionColumn'], function (CompositionColumn) { + var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f']; + describe("CompositionColumn", function () { var testIndex, + testIdMap, column; beforeEach(function () { testIndex = 3; - column = new CompositionColumn(testIndex); + testIdMap = TEST_IDS.reduce(function (map, id, index) { + map[id] = index; + return map; + }, {}); + column = new CompositionColumn(testIndex, testIdMap); }); it("includes a one-based index in its name", function () { @@ -46,15 +53,13 @@ define( 'domainObject', ['getId', 'getModel', 'getCapability'] ); - testModel = { - composition: ['a', 'b', 'c', 'd', 'e', 'f'] - }; + testModel = { composition: TEST_IDS }; mockDomainObject.getModel.andReturn(testModel); }); - it("returns a corresponding identifier", function () { + it("returns a corresponding value from the map", function () { expect(column.value(mockDomainObject)) - .toEqual(testModel.composition[testIndex]); + .toEqual(testIdMap[testModel.composition[testIndex]]); }); it("returns nothing when composition is exceeded", function () { diff --git a/platform/features/timeline/test/actions/IdColumnSpec.js b/platform/features/timeline/test/actions/IdColumnSpec.js index f44d255255..80b84680a4 100644 --- a/platform/features/timeline/test/actions/IdColumnSpec.js +++ b/platform/features/timeline/test/actions/IdColumnSpec.js @@ -24,10 +24,12 @@ define( ['../../src/actions/IdColumn'], function (IdColumn) { describe("IdColumn", function () { - var column; + var testIdMap, + column; beforeEach(function () { - column = new IdColumn(); + testIdMap = { "foo": "bar" }; + column = new IdColumn(testIdMap); }); it("has a name", function () { @@ -47,9 +49,9 @@ define( mockDomainObject.getId.andReturn(testId); }); - it("provides a domain object's identifier", function () { + it("provides a value mapped from domain object's identifier", function () { expect(column.value(mockDomainObject)) - .toEqual(testId); + .toEqual(testIdMap[testId]); }); }); diff --git a/platform/features/timeline/test/actions/ModeColumnSpec.js b/platform/features/timeline/test/actions/ModeColumnSpec.js index 446e3b1030..b828511266 100644 --- a/platform/features/timeline/test/actions/ModeColumnSpec.js +++ b/platform/features/timeline/test/actions/ModeColumnSpec.js @@ -23,13 +23,20 @@ define( ['../../src/actions/ModeColumn'], function (ModeColumn) { + var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f'] + describe("ModeColumn", function () { var testIndex, + testIdMap, column; beforeEach(function () { testIndex = 3; - column = new ModeColumn(testIndex); + testIdMap = TEST_IDS.reduce(function (map, id, index) { + map[id] = index; + return map; + }, {}); + column = new ModeColumn(testIndex, testIdMap); }); it("includes a one-based index in its name", function () { @@ -48,15 +55,15 @@ define( ); testModel = { relationships: { - modes: ['a', 'b', 'c', 'd', 'e', 'f'] + modes: TEST_IDS } }; mockDomainObject.getModel.andReturn(testModel); }); - it("returns a corresponding identifier", function () { + it("returns a corresponding value from the map", function () { expect(column.value(mockDomainObject)) - .toEqual(testModel.relationships.modes[testIndex]); + .toEqual(testIdMap[testModel.relationships.modes[testIndex]]); }); it("returns nothing when relationships are exceeded", function () { diff --git a/platform/features/timeline/test/actions/TimelineColumnizerSpec.js b/platform/features/timeline/test/actions/TimelineColumnizerSpec.js index 3c9b3de7e6..980ed1e6c3 100644 --- a/platform/features/timeline/test/actions/TimelineColumnizerSpec.js +++ b/platform/features/timeline/test/actions/TimelineColumnizerSpec.js @@ -94,13 +94,6 @@ define( it("include one row per domain object", function () { expect(rows.length).toEqual(mockDomainObjects.length); }); - - it("includes identifiers for each domain object", function () { - rows.forEach(function (row, index) { - var id = mockDomainObjects[index].getId(); - expect(row.indexOf(id)).not.toEqual(-1); - }); - }); }); describe("headers", function () { From f9fd97230ff902929cbfceb03b703dc3e371375b Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 25 May 2016 12:37:03 -0700 Subject: [PATCH 16/24] [Timeline] Satisfy JSHint --- .../features/timeline/src/actions/TimelineColumnizer.js | 8 -------- .../features/timeline/src/actions/UtilizationColumn.js | 3 --- platform/features/timeline/test/actions/ModeColumnSpec.js | 2 +- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index fb0b80a7f7..011e87df9e 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -85,14 +85,6 @@ define([ } } - function addCostProperties(costCapability) { - costCapability.resources().forEach(function (key) { - if (costKeys.indexOf(key) === -1) { - costKeys.push(key); - } - }); - } - idMap = domainObjects.reduce(function (map, domainObject, index) { map[domainObject.getId()] = index + 1; return map; diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js index e87794237b..9c9307271e 100644 --- a/platform/features/timeline/src/actions/UtilizationColumn.js +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -19,11 +19,8 @@ * this source code distribution or the Licensing information page available * at runtime from the About dialog for additional information. *****************************************************************************/ -/*global define*/ define([], function () { - "use strict"; - /** * A column showing utilization costs associated with activities. * @constructor diff --git a/platform/features/timeline/test/actions/ModeColumnSpec.js b/platform/features/timeline/test/actions/ModeColumnSpec.js index b828511266..037aa5c34f 100644 --- a/platform/features/timeline/test/actions/ModeColumnSpec.js +++ b/platform/features/timeline/test/actions/ModeColumnSpec.js @@ -23,7 +23,7 @@ define( ['../../src/actions/ModeColumn'], function (ModeColumn) { - var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f'] + var TEST_IDS = ['a', 'b', 'c', 'd', 'e', 'f']; describe("ModeColumn", function () { var testIndex, From bde2bc77099b616021bc54441e246bde71317223 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Wed, 25 May 2016 19:28:28 -0700 Subject: [PATCH 17/24] [Frontend] Bottom of holder divs adjusted open #913 --- platform/features/timeline/res/sass/_timelines.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/platform/features/timeline/res/sass/_timelines.scss b/platform/features/timeline/res/sass/_timelines.scss index 251008a64c..006fccfbd9 100644 --- a/platform/features/timeline/res/sass/_timelines.scss +++ b/platform/features/timeline/res/sass/_timelines.scss @@ -52,6 +52,9 @@ // Tree area with item title right: auto; // Set this to auto and uncomment width below when additional tabular columns are added width: $timelineTabularTitleW; + .l-swimlanes-holder { + bottom: $scrollbarTrackSize; + } } &.l-tabular-r { // Start, end, duration, activity modes columns @@ -67,6 +70,7 @@ &.l-timeline-gantt { .l-swimlanes-holder { @include scrollV(scroll); + bottom: $scrollbarTrackSize; } } &.l-timeline-resource-legend { From c557fb6cd5a2c2d0a48df4517445fe93159c623a Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Wed, 25 May 2016 19:39:56 -0700 Subject: [PATCH 18/24] [Frontend] Cursor properties modified open #768 --- platform/features/timeline/res/sass/_activities.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/features/timeline/res/sass/_activities.scss b/platform/features/timeline/res/sass/_activities.scss index 5e729432f7..268c602ae8 100644 --- a/platform/features/timeline/res/sass/_activities.scss +++ b/platform/features/timeline/res/sass/_activities.scss @@ -59,7 +59,7 @@ .handle { cursor: col-resize; &.mid { - cursor: move; + cursor: ew-resize; } } } \ No newline at end of file From 33c208d8fe7cb2589b59f3a1e20bb57809d5730a Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Wed, 25 May 2016 20:52:36 -0700 Subject: [PATCH 19/24] [Frontend] Timeline Gantt bar mods to allow small min-width open #965 - CSS adjusted to handle min-width of 2px and better approach to ellipsizing text; - Angular ng-class added to hide icon and title if width less than a value; - Rounded corners on bars removed; --- .../timeline/res/sass/_activities.scss | 18 +++++++++++++++--- .../timeline/res/sass/_timeline-thematic.scss | 10 ---------- .../timeline/res/templates/activity-gantt.html | 1 + 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/platform/features/timeline/res/sass/_activities.scss b/platform/features/timeline/res/sass/_activities.scss index 268c602ae8..cfe69d6d01 100644 --- a/platform/features/timeline/res/sass/_activities.scss +++ b/platform/features/timeline/res/sass/_activities.scss @@ -1,16 +1,22 @@ .l-timeline-gantt { + min-width: 2px; + overflow: hidden; position: absolute; top: $timelineSwimlaneGanttVM; bottom: $timelineSwimlaneGanttVM; .bar { @include ellipsize(); height: $activityBarH; - line-height: $activityBarH + 2; + line-height: $activityBarH; padding: 0 $interiorMargin; span { - display: inline; + $iconW: 20px; + @include absPosDefault(); + display: block; &.s-activity-type { + right: auto; width: $iconW; + text-align: center; &.timeline { &:before { content:"S"; @@ -23,7 +29,9 @@ } } &.s-title { - text-shadow: rgba(black, 0.1) 0 1px 2px; + overflow: hidden; + text-overflow: ellipsis; + left: $iconW; } &.duration { left: auto; @@ -52,6 +60,10 @@ } } } + &.sm .bar span { + // Hide icon and label if width is too small + display: none; + } } .edit-mode .s-timeline-gantt, diff --git a/platform/features/timeline/res/sass/_timeline-thematic.scss b/platform/features/timeline/res/sass/_timeline-thematic.scss index 967a07462f..d4ab58b6e7 100644 --- a/platform/features/timeline/res/sass/_timeline-thematic.scss +++ b/platform/features/timeline/res/sass/_timeline-thematic.scss @@ -32,20 +32,10 @@ } .s-timeline-gantt { - $br: $controlCr; .bar { color: $colorGanttBarFg; @include activityBg($colorGanttBarBg); - border-radius: $br; box-shadow: $shdwGanttBar; - &.expanded { - @include border-top-radius($br); - @include border-bottom-radius(0); - } - &.leaf { - @include border-top-radius(0); - @include border-bottom-radius($br); - } .s-toggle { color: $colorGanttToggle; } diff --git a/platform/features/timeline/res/templates/activity-gantt.html b/platform/features/timeline/res/templates/activity-gantt.html index 69d1d8984a..1615431e91 100644 --- a/platform/features/timeline/res/templates/activity-gantt.html +++ b/platform/features/timeline/res/templates/activity-gantt.html @@ -20,6 +20,7 @@ at runtime from the About dialog for additional information. -->
Date: Thu, 26 May 2016 11:53:16 -0700 Subject: [PATCH 21/24] [Timeline] Add JSDoc for idMap https://github.com/nasa/openmct/pull/962#discussion_r64676750 https://github.com/nasa/openmct/pull/962#discussion_r64677198 --- platform/features/timeline/src/actions/CompositionColumn.js | 3 +++ platform/features/timeline/src/actions/IdColumn.js | 5 ++++- platform/features/timeline/src/actions/ModeColumn.js | 3 +++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/platform/features/timeline/src/actions/CompositionColumn.js b/platform/features/timeline/src/actions/CompositionColumn.js index 3fff0bda37..e33f028f99 100644 --- a/platform/features/timeline/src/actions/CompositionColumn.js +++ b/platform/features/timeline/src/actions/CompositionColumn.js @@ -27,6 +27,9 @@ define([], function () { * in a domain object's composition. * @param {number} index the zero-based index of the composition * element associated with this column + * @param idMap an object containing key value pairs, where keys + * are domain object identifiers and values are whatever + * should appear in CSV output in their place * @constructor * @implements {platform/features/timeline.TimelineCSVColumn} */ diff --git a/platform/features/timeline/src/actions/IdColumn.js b/platform/features/timeline/src/actions/IdColumn.js index b6ff15fe6c..9148ef6a8b 100644 --- a/platform/features/timeline/src/actions/IdColumn.js +++ b/platform/features/timeline/src/actions/IdColumn.js @@ -23,8 +23,11 @@ define([], function () { /** - * A column showing domain object identifiers. + * A column showing identifying domain objects. * @constructor + * @param idMap an object containing key value pairs, where keys + * are domain object identifiers and values are whatever + * should appear in CSV output in their place * @implements {platform/features/timeline.TimelineCSVColumn} */ function IdColumn(idMap) { diff --git a/platform/features/timeline/src/actions/ModeColumn.js b/platform/features/timeline/src/actions/ModeColumn.js index 26b307cbd0..05eec7a30a 100644 --- a/platform/features/timeline/src/actions/ModeColumn.js +++ b/platform/features/timeline/src/actions/ModeColumn.js @@ -27,6 +27,9 @@ define([], function () { * @constructor * @param {number} index the zero-based index of the composition * element associated with this column + * @param idMap an object containing key value pairs, where keys + * are domain object identifiers and values are whatever + * should appear in CSV output in their place * @implements {platform/features/timeline.TimelineCSVColumn} */ function ModeColumn(index, idMap) { From e9cac6eff3d88a7524edfddcb864a212aa716440 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 26 May 2016 11:57:07 -0700 Subject: [PATCH 22/24] [Timeline] Add JSDoc for new parameter https://github.com/nasa/openmct/pull/962#discussion_r64677520 --- platform/features/timeline/src/actions/TimelineColumnizer.js | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/features/timeline/src/actions/TimelineColumnizer.js b/platform/features/timeline/src/actions/TimelineColumnizer.js index 011e87df9e..92e54b1860 100644 --- a/platform/features/timeline/src/actions/TimelineColumnizer.js +++ b/platform/features/timeline/src/actions/TimelineColumnizer.js @@ -65,6 +65,7 @@ define([ * * @param {DomainObject[]} domainObjects the objects to include * in the exported data + * @param {Array} resources an array of `resources` extensions * @constructor * @memberof {platform/features/timeline} */ From dade6b2254f85b72b6cf61a5c198885d8c532eb6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 26 May 2016 11:58:40 -0700 Subject: [PATCH 23/24] [Timeline] Use positive logic for clarity https://github.com/nasa/openmct/pull/962#discussion_r64678013 --- platform/features/timeline/src/actions/UtilizationColumn.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/platform/features/timeline/src/actions/UtilizationColumn.js b/platform/features/timeline/src/actions/UtilizationColumn.js index 9c9307271e..7a92ce668e 100644 --- a/platform/features/timeline/src/actions/UtilizationColumn.js +++ b/platform/features/timeline/src/actions/UtilizationColumn.js @@ -62,10 +62,10 @@ define([], function () { }, 0); } - return !domainObject.hasCapability('utilization') ? - "" : + return domainObject.hasCapability('utilization') ? domainObject.getCapability('utilization').internal() - .then(getUtilizationValue); + .then(getUtilizationValue) : + ""; }; return UtilizationColumn; From 9820f9d9c5b24f0676f400f080d911e3f09f9046 Mon Sep 17 00:00:00 2001 From: Charles Hacskaylo Date: Thu, 26 May 2016 12:45:25 -0700 Subject: [PATCH 24/24] [Frontend] Mod CSS to properly hide nav-to-parent when editing fixes #970 Not sure what problem was, but betting this was due to removal of an ng-class previously in markup; --- platform/commonUI/general/res/sass/user-environ/_layout.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/commonUI/general/res/sass/user-environ/_layout.scss b/platform/commonUI/general/res/sass/user-environ/_layout.scss index 9e8e9aaae1..8537c85520 100644 --- a/platform/commonUI/general/res/sass/user-environ/_layout.scss +++ b/platform/commonUI/general/res/sass/user-environ/_layout.scss @@ -288,8 +288,9 @@ body.desktop .pane .mini-tab-icon.toggle-pane { .left { padding-right: $interiorMarginLg; - .l-back:not(.s-status-editing) { + .l-back { margin-right: $interiorMarginLg; + &.s-status-editing { display: none; } } } }