Merge pull request #2356 from kravets-levko/fix/dashboard-auto-height

Dashboard fixes and improvements
This commit is contained in:
Arik Fraimovich 2018-03-04 14:50:48 +02:00 committed by GitHub
commit 6049e2df17
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 97 additions and 43 deletions

View File

@ -1,15 +1,37 @@
import * as _ from 'underscore'; import * as _ from 'underscore';
import { requestAnimationFrame } from './utils'; import { requestAnimationFrame } from './utils';
function gridsterAutoHeight($timeout) { function gridsterAutoHeight($timeout, $parse) {
return { return {
restrict: 'A', restrict: 'A',
require: 'gridsterItem', require: 'gridsterItem',
link($scope, $element, attr, controller) { link($scope, $element, attr, controller) {
let destroyed = false; let autoSized = true;
const itemGetter = $parse(attr.gridsterItem);
$scope.$watch(attr.gridsterItem, (newValue, oldValue) => {
const item = _.extend({}, itemGetter($scope));
if (_.isObject(newValue) && _.isObject(oldValue)) {
if ((newValue.sizeY !== oldValue.sizeY) && !autoSized) {
item.autoHeight = false;
if (_.isFunction(itemGetter.assign)) {
itemGetter.assign($scope, item);
}
}
}
if (item.autoHeight) {
$element.addClass('gridster-auto-height-enabled');
} else {
$element.removeClass('gridster-auto-height-enabled');
}
autoSized = false;
}, true);
function updateHeight() { function updateHeight() {
if (controller.gridster) { const item = _.extend({}, itemGetter($scope));
if (controller.gridster && item.autoHeight) {
const wrapper = $element[0]; const wrapper = $element[0];
// Query element, but keep selector order // Query element, but keep selector order
const element = _.chain(attr.gridsterAutoHeight.split(',')) const element = _.chain(attr.gridsterAutoHeight.split(','))
@ -31,25 +53,22 @@ function gridsterAutoHeight($timeout) {
const additionalHeight = 100 + _.last(controller.gridster.margins); const additionalHeight = 100 + _.last(controller.gridster.margins);
const contentsHeight = childrenBounds.bottom - childrenBounds.top; const contentsHeight = childrenBounds.bottom - childrenBounds.top;
$timeout(() => { $timeout(() => {
controller.sizeY = Math.ceil((contentsHeight + additionalHeight) / const sizeY = Math.ceil((contentsHeight + additionalHeight) /
controller.gridster.curRowHeight); controller.gridster.curRowHeight);
if (controller.sizeY !== sizeY) {
autoSized = true;
controller.sizeY = sizeY;
} else {
autoSized = false;
}
}); });
} }
if (!destroyed) {
requestAnimationFrame(updateHeight); requestAnimationFrame(updateHeight);
} }
} }
}
if (controller.sizeY < 0) {
$element.addClass('gridster-auto-height-enabled');
updateHeight(); updateHeight();
$scope.$on('$destroy', () => {
destroyed = true;
});
}
}, },
}; };
} }

View File

@ -5,6 +5,30 @@ import template from './dashboard.html';
import shareDashboardTemplate from './share-dashboard.html'; import shareDashboardTemplate from './share-dashboard.html';
import './dashboard.less'; import './dashboard.less';
function isWidgetPositionChanged(oldPosition, newPosition) {
const fields = ['col', 'row', 'sizeX', 'sizeY', 'autoHeight'];
oldPosition = _.pick(oldPosition, fields);
newPosition = _.pick(newPosition, fields);
return !!_.find(fields, key => newPosition[key] !== oldPosition[key]);
}
function collectWidgetPositions(widgets) {
return _.chain(widgets)
.map(widget => [widget.id, _.clone(widget.options.position)])
.object()
.value();
}
function getWidgetsWithChangedPositions(widgets, savedPositions) {
return _.filter(widgets, (widget) => {
const savedPosition = savedPositions[widget.id];
if (!_.isObject(savedPosition)) {
return true;
}
return isWidgetPositionChanged(savedPosition, widget.options.position);
});
}
function DashboardCtrl( function DashboardCtrl(
$rootScope, $rootScope,
$routeParams, $routeParams,
@ -22,7 +46,11 @@ function DashboardCtrl(
toastr, toastr,
) { ) {
this.saveInProgress = false; this.saveInProgress = false;
const saveDashboardLayout = () => {
// This variable should always be in sync with widgets
let savedWidgetPositions = {};
const saveDashboardLayout = (widgets) => {
if (!this.dashboard.canEdit()) { if (!this.dashboard.canEdit()) {
return; return;
} }
@ -33,7 +61,7 @@ function DashboardCtrl(
this.dashboardGridOptions.draggable.enabled = false; this.dashboardGridOptions.draggable.enabled = false;
this.dashboardGridOptions.resizable.enabled = false; this.dashboardGridOptions.resizable.enabled = false;
return $q return $q
.all(_.map(this.dashboard.widgets, widget => widget.$save())) .all(_.map(widgets, widget => widget.$save()))
.then(() => { .then(() => {
if (showMessages) { if (showMessages) {
toastr.success('Changes saved.'); toastr.success('Changes saved.');
@ -181,6 +209,8 @@ function DashboardCtrl(
$location.search('edit', null); $location.search('edit', null);
this.editLayout(true); this.editLayout(true);
} }
savedWidgetPositions = collectWidgetPositions(dashboard.widgets);
}, },
(rejection) => { (rejection) => {
const statusGroup = Math.floor(rejection.status / 100); const statusGroup = Math.floor(rejection.status / 100);
@ -233,26 +263,26 @@ function DashboardCtrl(
if (enableEditing) { if (enableEditing) {
if (!this.layoutEditing) { if (!this.layoutEditing) {
// Save current positions of widgets // Save current positions of widgets
_.each(this.dashboard.widgets, (widget) => { savedWidgetPositions = collectWidgetPositions(this.dashboard.widgets);
widget.$savedPosition = _.clone(widget.options.position);
});
} }
} else { } else {
if (applyChanges) { if (applyChanges) {
// Clear saved data and save layout const changedWidgets = getWidgetsWithChangedPositions(
_.each(this.dashboard.widgets, (widget) => { this.dashboard.widgets,
widget.$savedPosition = undefined; savedWidgetPositions,
);
saveDashboardLayout(changedWidgets).finally(() => {
savedWidgetPositions = collectWidgetPositions(this.dashboard.widgets);
}); });
saveDashboardLayout();
} else { } else {
// Revert changes // Revert changes
_.each(this.dashboard.widgets, (widget) => { _.each(this.dashboard.widgets, (widget) => {
if (_.isObject(widget.$savedPosition)) { if (_.isObject(savedWidgetPositions[widget.id])) {
widget.options.position = widget.$savedPosition; widget.options.position = savedWidgetPositions[widget.id];
} }
widget.$savedPosition = undefined;
}); });
} }
savedWidgetPositions = collectWidgetPositions(this.dashboard.widgets);
} }
this.layoutEditing = enableEditing; this.layoutEditing = enableEditing;
@ -297,20 +327,15 @@ function DashboardCtrl(
}) })
.result.then(() => { .result.then(() => {
this.extractGlobalParameters(); this.extractGlobalParameters();
if (this.layoutEditing) {
// Save position of newly added widget (but not entire layout) // Save position of newly added widget (but not entire layout)
const widget = _.last(this.dashboard.widgets); const widget = _.last(this.dashboard.widgets);
if (_.isObject(widget)) { if (_.isObject(widget)) {
return widget.$save().then(() => { return widget.$save().then(() => {
if (this.layoutEditing) { if (this.layoutEditing) {
widget.$savedPosition = _.clone(widget.options.position); savedWidgetPositions[widget.id] = _.clone(widget.options.position);
} }
}); });
} }
} else {
// Update entire layout
return saveDashboardLayout();
}
}); });
}; };
@ -320,7 +345,13 @@ function DashboardCtrl(
// We need to wait a bit for `angular-gridster` before it updates widgets, // We need to wait a bit for `angular-gridster` before it updates widgets,
// and only then save new layout // and only then save new layout
$timeout(() => { $timeout(() => {
saveDashboardLayout(); const changedWidgets = getWidgetsWithChangedPositions(
this.dashboard.widgets,
savedWidgetPositions,
);
saveDashboardLayout(changedWidgets).finally(() => {
savedWidgetPositions = collectWidgetPositions(this.dashboard.widgets);
});
}, 50); }, 50);
} }
}; };

View File

@ -103,9 +103,13 @@ function Widget($resource, $http, Query, Visualization, dashboardGridOptions) {
widget.options.position = extend( widget.options.position = extend(
{}, {},
visualizationOptions, visualizationOptions,
pick(widget.options.position, ['col', 'row', 'sizeX', 'sizeY']), pick(widget.options.position, ['col', 'row', 'sizeX', 'sizeY', 'autoHeight']),
); );
if (widget.options.position.sizeY < 0) {
widget.options.position.autoHeight = true;
}
return new WidgetResource(widget); return new WidgetResource(widget);
} }

View File

@ -20,7 +20,7 @@ const DISPLAY_AS_OPTIONS = [
const DEFAULT_OPTIONS = { const DEFAULT_OPTIONS = {
itemsPerPage: 15, itemsPerPage: 15,
defaultRows: -1, defaultRows: -1,
defaultColumns: 4, defaultColumns: 3,
minColumns: 2, minColumns: 2,
}; };