mirror of
https://github.com/nasa/openmct.git
synced 2024-12-18 20:57:53 +00:00
Persist User preference widths for MCTSplitPane
Fix to Issue #1646 Persist MCTSplitPane widths to local storage, thus when user reloads, the Panes maintain dimensions Use persisted widths if available otherwise use default Add tests for localStorage and fix failing tests
This commit is contained in:
parent
5ac377ec6a
commit
449923feae
2
.gitignore
vendored
2
.gitignore
vendored
@ -36,3 +36,5 @@ protractor/logs
|
||||
|
||||
# npm-debug log
|
||||
npm-debug.log
|
||||
|
||||
package-lock.json
|
||||
|
@ -26,7 +26,7 @@
|
||||
ng-controller="PaneController as modelPaneTree"
|
||||
ng-class="modelPaneTree.visible() ? 'pane-tree-showing' : 'pane-tree-hidden'">
|
||||
<mct-split-pane class='abs contents'
|
||||
anchor='left'>
|
||||
anchor='left' alias="leftSide">
|
||||
<div class='split-pane-component treeview pane left'>
|
||||
<div class="abs holder l-flex-col holder-treeview-elements">
|
||||
<mct-representation key="'create-button'"
|
||||
@ -60,7 +60,7 @@
|
||||
ng-controller="InspectorPaneController as modelPaneInspect"
|
||||
ng-class="modelPaneInspect.visible() ? 'pane-inspect-showing' : 'pane-inspect-hidden'">
|
||||
|
||||
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right'>
|
||||
<mct-split-pane class='l-object-and-inspector contents abs' anchor='right' alias="rightSide">
|
||||
<div class='split-pane-component t-object pane primary-pane left'>
|
||||
<mct-representation mct-object="navigatedObject"
|
||||
key="navigatedObject.getCapability('status').get('editing') ? 'edit-object' : 'browse-object'"
|
||||
@ -87,4 +87,3 @@
|
||||
</div>
|
||||
<mct-include key="'bottombar'"></mct-include>
|
||||
</div>
|
||||
|
||||
|
@ -374,7 +374,8 @@ define([
|
||||
"depends": [
|
||||
"$parse",
|
||||
"$log",
|
||||
"$interval"
|
||||
"$interval",
|
||||
"$window"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -93,13 +93,21 @@ define(
|
||||
* @memberof platform/commonUI/general
|
||||
* @constructor
|
||||
*/
|
||||
function MCTSplitPane($parse, $log, $interval) {
|
||||
function MCTSplitPane($parse, $log, $interval, $window) {
|
||||
function controller($scope, $element, $attrs) {
|
||||
var anchorKey = $attrs.anchor || DEFAULT_ANCHOR,
|
||||
positionParsed = $parse($attrs.position),
|
||||
anchor,
|
||||
activeInterval,
|
||||
positionParsed = $parse($attrs.position),
|
||||
position; // Start undefined, until explicitly set
|
||||
position,
|
||||
splitterSize,
|
||||
|
||||
alias = $attrs.alias !== undefined ?
|
||||
"mctSplitPane-" + $attrs.alias : undefined,
|
||||
|
||||
//convert string to number from localStorage
|
||||
userWidthPreference = $window.localStorage.getItem(alias) === null ?
|
||||
undefined : Number($window.localStorage.getItem(alias));
|
||||
|
||||
// Get relevant size (height or width) of DOM element
|
||||
function getSize(domElement) {
|
||||
@ -114,11 +122,11 @@ define(
|
||||
var first = children.eq(anchor.reversed ? 2 : 0),
|
||||
splitter = children.eq(1),
|
||||
last = children.eq(anchor.reversed ? 0 : 2),
|
||||
splitterSize = getSize(splitter[0]),
|
||||
firstSize;
|
||||
|
||||
splitterSize = getSize(splitter[0]);
|
||||
first.css(anchor.edge, "0px");
|
||||
first.css(anchor.dimension, (position - splitterSize) + 'px');
|
||||
first.css(anchor.dimension, (userWidthPreference || position) + 'px');
|
||||
|
||||
// Get actual size (to obey min-width etc.)
|
||||
firstSize = getSize(first[0]);
|
||||
@ -126,9 +134,8 @@ define(
|
||||
splitter.css(anchor.edge, firstSize + 'px');
|
||||
splitter.css(anchor.opposite, "auto");
|
||||
|
||||
last.css(anchor.edge, (firstSize + splitterSize) + 'px');
|
||||
last.css(anchor.edge, firstSize + splitterSize + 'px');
|
||||
last.css(anchor.opposite, "0px");
|
||||
|
||||
position = firstSize + splitterSize;
|
||||
}
|
||||
|
||||
@ -169,6 +176,17 @@ define(
|
||||
return position;
|
||||
}
|
||||
|
||||
function setUserWidthPreference(value) {
|
||||
userWidthPreference = value - splitterSize;
|
||||
}
|
||||
|
||||
function persistToLocalStorage(value) {
|
||||
if (alias) {
|
||||
userWidthPreference = value - splitterSize;
|
||||
$window.localStorage.setItem(alias, userWidthPreference);
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamically apply a CSS class to elements when the user
|
||||
// is actively resizing
|
||||
function toggleClass(classToToggle) {
|
||||
@ -196,18 +214,31 @@ define(
|
||||
activeInterval = $interval(function () {
|
||||
getSetPosition(getSetPosition());
|
||||
}, POLLING_INTERVAL, 0, false);
|
||||
|
||||
// ...and stop polling when we're destroyed.
|
||||
$scope.$on('$destroy', function () {
|
||||
$interval.cancel(activeInterval);
|
||||
});
|
||||
|
||||
|
||||
// Interface exposed by controller, for mct-splitter to user
|
||||
return {
|
||||
position: getSetPosition,
|
||||
toggleClass: toggleClass,
|
||||
anchor: function () {
|
||||
return anchor;
|
||||
},
|
||||
position: function (value) {
|
||||
if (arguments.length > 0) {
|
||||
setUserWidthPreference(value);
|
||||
return getSetPosition(value);
|
||||
} else {
|
||||
return getSetPosition();
|
||||
}
|
||||
},
|
||||
startResizing: function () {
|
||||
toggleClass('resizing');
|
||||
},
|
||||
endResizing: function (finalPosition) {
|
||||
persistToLocalStorage(finalPosition);
|
||||
toggleClass('resizing');
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -219,9 +250,7 @@ define(
|
||||
controller: ['$scope', '$element', '$attrs', controller]
|
||||
};
|
||||
}
|
||||
|
||||
return MCTSplitPane;
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -37,15 +37,16 @@ define(
|
||||
*/
|
||||
function MCTSplitter() {
|
||||
function link(scope, element, attrs, mctSplitPane) {
|
||||
var initialPosition;
|
||||
var initialPosition,
|
||||
newPosition;
|
||||
|
||||
element.addClass("splitter");
|
||||
|
||||
scope.splitter = {
|
||||
// Begin moving this splitter
|
||||
startMove: function () {
|
||||
mctSplitPane.startResizing();
|
||||
initialPosition = mctSplitPane.position();
|
||||
mctSplitPane.toggleClass('resizing');
|
||||
},
|
||||
// Handle user changes to splitter position
|
||||
move: function (delta) {
|
||||
@ -55,12 +56,13 @@ define(
|
||||
(anchor.reversed ? -1 : 1);
|
||||
|
||||
// Update the position of this splitter
|
||||
mctSplitPane.position(initialPosition + pixelDelta);
|
||||
newPosition = initialPosition + pixelDelta;
|
||||
mctSplitPane.position(newPosition);
|
||||
},
|
||||
// Grab the event when the user is done moving
|
||||
// the splitter and pass it on
|
||||
endMove: function () {
|
||||
mctSplitPane.toggleClass('resizing');
|
||||
mctSplitPane.endResizing(newPosition);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -83,4 +85,3 @@ define(
|
||||
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -38,7 +38,8 @@ define(
|
||||
mockLog,
|
||||
mockInterval,
|
||||
mockParsed,
|
||||
mctSplitPane;
|
||||
mctSplitPane,
|
||||
mockWindow = {};
|
||||
|
||||
beforeEach(function () {
|
||||
mockParse = jasmine.createSpy('$parse');
|
||||
@ -48,13 +49,23 @@ define(
|
||||
mockInterval.cancel = jasmine.createSpy('mockCancel');
|
||||
mockParsed = jasmine.createSpy('parsed');
|
||||
mockParsed.assign = jasmine.createSpy('assign');
|
||||
|
||||
mockParse.andReturn(mockParsed);
|
||||
|
||||
mockWindow.localStorage = {
|
||||
store: {},
|
||||
setItem: function (key, value) {
|
||||
this.store[key] = value;
|
||||
},
|
||||
getItem: function (key) {
|
||||
return this.store[key];
|
||||
}
|
||||
};
|
||||
|
||||
mctSplitPane = new MCTSplitPane(
|
||||
mockParse,
|
||||
mockLog,
|
||||
mockInterval
|
||||
mockInterval,
|
||||
mockWindow
|
||||
);
|
||||
});
|
||||
|
||||
@ -85,7 +96,7 @@ define(
|
||||
jasmine.createSpyObj('$scope', ['$apply', '$watch', '$on']);
|
||||
mockElement =
|
||||
jasmine.createSpyObj('element', JQLITE_METHODS);
|
||||
testAttrs = {};
|
||||
testAttrs = {alias: 'rightSide'};
|
||||
mockChildren =
|
||||
jasmine.createSpyObj('children', JQLITE_METHODS);
|
||||
mockFirstPane =
|
||||
@ -142,10 +153,14 @@ define(
|
||||
});
|
||||
});
|
||||
|
||||
it("allows classes to be toggled on contained elements", function () {
|
||||
controller.toggleClass('resizing');
|
||||
expect(mockChildren.toggleClass)
|
||||
.toHaveBeenCalledWith('resizing');
|
||||
it("applies resizing class to children when resizing", function () {
|
||||
controller.startResizing();
|
||||
expect(mockChildren.toggleClass).toHaveBeenCalledWith('resizing');
|
||||
});
|
||||
|
||||
it("removes resizing class from children when resizing action ends", function () {
|
||||
controller.endResizing(0);
|
||||
expect(mockChildren.toggleClass).toHaveBeenCalledWith('resizing');
|
||||
});
|
||||
|
||||
it("allows positions to be set", function () {
|
||||
@ -198,6 +213,12 @@ define(
|
||||
fireOn('$destroy');
|
||||
expect(mockInterval.cancel).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("saves user preference to localStorage when user is done resizing", function () {
|
||||
controller.endResizing(100);
|
||||
expect(Number(mockWindow.localStorage.getItem('mctSplitPane-rightSide'))).toEqual(100 - mockSplitter[0].offsetWidth);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ define(
|
||||
testAttrs = {};
|
||||
mockSplitPane = jasmine.createSpyObj(
|
||||
'mctSplitPane',
|
||||
['position', 'toggleClass', 'anchor']
|
||||
['position', 'startResizing', 'endResizing', 'anchor']
|
||||
);
|
||||
|
||||
mctSplitter.link(
|
||||
@ -86,9 +86,9 @@ define(
|
||||
mockScope.splitter.startMove();
|
||||
});
|
||||
|
||||
it("adds a 'resizing' class", function () {
|
||||
expect(mockSplitPane.toggleClass)
|
||||
.toHaveBeenCalledWith('resizing');
|
||||
it("tell's the splitter when it is resizing", function () {
|
||||
expect(mockSplitPane.startResizing)
|
||||
.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("repositions during drag", function () {
|
||||
@ -97,11 +97,10 @@ define(
|
||||
.toHaveBeenCalledWith(testPosition + 10);
|
||||
});
|
||||
|
||||
it("removes the 'resizing' class when finished", function () {
|
||||
mockSplitPane.toggleClass.reset();
|
||||
it("tell's the splitter when it is done resizing", function () {
|
||||
mockScope.splitter.move([10,0]);
|
||||
mockScope.splitter.endMove();
|
||||
expect(mockSplitPane.toggleClass)
|
||||
.toHaveBeenCalledWith('resizing');
|
||||
expect(mockSplitPane.endResizing).toHaveBeenCalledWith(testPosition + 10);
|
||||
});
|
||||
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user