Skip to content

Commit

Permalink
gridstack: optimizations and bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kravets-levko committed Mar 23, 2018
1 parent ce9e3fc commit 2fbf892
Show file tree
Hide file tree
Showing 13 changed files with 407 additions and 84 deletions.
29 changes: 0 additions & 29 deletions client/app/assets/less/inc/gridster.less

This file was deleted.

2 changes: 0 additions & 2 deletions client/app/assets/less/main.less
Expand Up @@ -9,7 +9,6 @@
@import '~ui-select/dist/select.css';
@import '~angular-toastr/src/toastr';
@import '~angular-resizable/src/angular-resizable.css';
@import '~angular-gridster/src/angular-gridster';
@import '~pace-progress/themes/blue/pace-theme-minimal.css';
@import '~material-design-iconic-font/dist/css/material-design-iconic-font.css';

Expand Down Expand Up @@ -51,7 +50,6 @@
@import 'inc/navbar';
@import 'inc/edit-in-place';
@import 'inc/growl';
@import 'inc/gridster';
@import 'inc/flex';
@import 'inc/ace-editor';
@import 'inc/overlay';
Expand Down
3 changes: 0 additions & 3 deletions client/app/components/dashboards/gridstack/gridstack.js
Expand Up @@ -5,9 +5,6 @@ import 'jquery-ui/ui/widgets/droppable';
import 'jquery-ui/ui/widgets/resizable';
import 'gridstack/dist/gridstack.css';

window.$ = window.jQuery = $;
window._ = _;

// eslint-disable-next-line import/first
import gridstack from 'gridstack';

Expand Down
58 changes: 48 additions & 10 deletions client/app/components/dashboards/gridstack/index.js
Expand Up @@ -59,13 +59,14 @@ function computeAutoHeight($element, grid, node, minHeight, maxHeight) {
return Math.min(Math.max(minHeight, resultHeight), maxHeight);
}

function gridstack() {
function gridstack($parse, dashboardGridOptions) {
return {
restrict: 'A',
replace: false,
scope: {
editing: '=',
batchUpdate: '=', // set by directive - for using in wrapper components
isOneColumnMode: '=',
},
controller() {
this.$el = null;
Expand Down Expand Up @@ -205,16 +206,22 @@ function gridstack() {
};
},
link: ($scope, $element, $attr, controller) => {
const batchUpdateAssignable = _.isFunction($parse($attr.batchUpdate).assign);
const isOneColumnModeAssignable = _.isFunction($parse($attr.batchUpdate).assign);

let enablePolling = true;

$element.addClass('grid-stack');
$element.gridstack({
auto: false,
verticalMargin: 15,
cellHeight: 35, // real row height will be `cellHeight` + `verticalMargin`
width: 6, // columns
verticalMargin: dashboardGridOptions.margins,
// real row height will be `cellHeight` + `verticalMargin`
cellHeight: dashboardGridOptions.rowHeight - dashboardGridOptions.margins,
width: dashboardGridOptions.columns, // columns
height: 0, // max rows (0 for unlimited)
animate: true,
float: false,
minWidth: 800,
minWidth: dashboardGridOptions.mobileBreakPoint,
resizable: {
handles: 'e, se, s, sw, w',
start: (event, ui) => {
Expand Down Expand Up @@ -253,25 +260,56 @@ function gridstack() {
});
controller.$el = $element;

$element.on('change', (event, nodes) => {
nodes = _.isArray(nodes) ? nodes : [];
console.log('+', nodes.length);
_.each(nodes, (node) => {
// `change` events sometimes fire too frequently (for example,
// on initial rendering when all widgets add themselves to grid, grid
// will fire `change` event will _all_ items available at that moment).
// Collect changed items, and then delegate event with some delay
let changedNodes = {};
const triggerChange = _.debounce(() => {
_.each(changedNodes, (node) => {
if (node.el) {
$(node.el).trigger('gridstack.changed', node);
}
});
changedNodes = {};
});

$element.on('change', (event, nodes) => {
nodes = _.isArray(nodes) ? nodes : [];
_.each(nodes, (node) => {
changedNodes[node.id] = node;
});
triggerChange();
});

$scope.$watch('editing', (value) => {
controller.setEditing(!!value);
});

$scope.batchUpdate = controller.batchUpdateWidgets;
if (batchUpdateAssignable) {
$scope.batchUpdate = controller.batchUpdateWidgets;
}

$scope.$on('$destroy', () => {
enablePolling = false;
controller.$el = null;
});

function updateOneColumnMode() {
const grid = controller.grid();
if (grid) {
$scope.isOneColumnMode = $element.hasClass(grid.opts.oneColumnModeClass);
$scope.$applyAsync();
}

if (enablePolling) {
setTimeout(updateOneColumnMode, 150);
}
}

if (isOneColumnModeAssignable) {
updateOneColumnMode();
}
},
};
}
Expand Down
26 changes: 4 additions & 22 deletions client/app/config/dashboard-grid-options.js
@@ -1,33 +1,15 @@
const dashboardGridOptions = {
columns: 6,
pushing: true,
floating: true,
swapping: false,
width: 'auto',
colWidth: 'auto',
rowHeight: 50,
margins: [15, 15],
outerMargin: false,
sparse: false,
isMobile: false,
columns: 6, // grid columns count
rowHeight: 50, // grid row height (incl. bottom padding)
margins: 15, // widget margins
mobileBreakPoint: 800,
mobileModeEnabled: true,
minColumns: 6,
minRows: 1,
maxRows: 1000,
// defaults for widgets
defaultSizeX: 3,
defaultSizeY: 3,
minSizeX: 1,
maxSizeX: 6,
minSizeY: 1,
maxSizeY: 1000,
resizable: {
enabled: false,
handles: ['n', 'e', 's', 'w', 'ne', 'se', 'sw', 'nw'],
},
draggable: {
enabled: false,
},
};

export default function init(ngModule) {
Expand Down
2 changes: 0 additions & 2 deletions client/app/config/index.js
Expand Up @@ -17,7 +17,6 @@ import 'angular-moment';
import 'brace';
import 'angular-ui-ace';
import 'angular-resizable';
import ngGridster from 'angular-gridster';
import { each, isFunction } from 'underscore';

import '@/lib/sortable';
Expand Down Expand Up @@ -52,7 +51,6 @@ const requirements = [
'angularResizable',
vsRepeat,
'ui.sortable',
ngGridster.name,
];

const ngModule = angular.module('app', requirements);
Expand Down
1 change: 0 additions & 1 deletion client/app/config/styles.js
Expand Up @@ -3,7 +3,6 @@ import 'font-awesome/css/font-awesome.css';
import 'ui-select/dist/select.css';
import 'angular-toastr/dist/angular-toastr.css';
import 'angular-resizable/src/angular-resizable.css';
import 'angular-gridster/dist/angular-gridster.css';
import 'pace-progress/themes/blue/pace-theme-minimal.css';

import '@/assets/css/superflat_redash.css';
Expand Down
3 changes: 2 additions & 1 deletion client/app/pages/dashboards/dashboard.html
Expand Up @@ -85,7 +85,8 @@ <h3>
</div>

<div style="padding-bottom: 5px;" ng-if="$ctrl.dashboard.widgets.length > 0">
<div gridstack editing="$ctrl.layoutEditing && !$ctrl.saveInProgress" batch-update="$ctrl.updateGridItems" class="dashboard-wrapper"
<div gridstack editing="$ctrl.layoutEditing && !$ctrl.saveInProgress" batch-update="$ctrl.updateGridItems"
is-one-column-mode="$ctrl.isGridDisabled" class="dashboard-wrapper"
ng-class="{'preview-mode': !$ctrl.layoutEditing, 'editing-mode': $ctrl.layoutEditing}">
<div class="dashboard-widget-wrapper"
ng-repeat="widget in $ctrl.dashboard.widgets track by widget.id"
Expand Down
3 changes: 1 addition & 2 deletions client/app/pages/dashboards/dashboard.js
Expand Up @@ -304,8 +304,7 @@ function DashboardCtrl(
this.removeWidget = () => {
this.extractGlobalParameters();
if (!this.layoutEditing) {
// We need to wait a bit for `angular-gridster` before it updates widgets,
// and only then save new layout
// We need to wait a bit while `angular` updates widgets, and only then save new layout
$timeout(() => {
const changedWidgets = getWidgetsWithChangedPositions(this.dashboard.widgets);
saveDashboardLayout(changedWidgets);
Expand Down
12 changes: 8 additions & 4 deletions client/app/pages/dashboards/public-dashboard-page.html
Expand Up @@ -6,10 +6,14 @@
<filters ng-if="$ctrl.dashboard.dashboard_filters_enabled"></filters>
</div>

<div style="padding-bottom: 5px">
<div gridster="$ctrl.dashboardGridOptions" class="dashboard-wrapper">
<div ng-repeat="widget in $ctrl.dashboard.widgets" gridster-item="widget.options.position" gridster-auto-height>
<dashboard-widget widget="widget" dashboard="$ctrl.dashboard" public="true"></dashboard-widget>
<div style="padding-bottom: 5px" ng-if="$ctrl.dashboard.widgets.length > 0">
<div gridstack editing="false" class="dashboard-wrapper preview-mode">
<div class="dashboard-widget-wrapper"
ng-repeat="widget in $ctrl.dashboard.widgets"
gridstack-item="widget.options.position" gridstack-item-id="{{ widget.id }}">
<div class="grid-stack-item-content">
<dashboard-widget widget="widget" dashboard="$ctrl.dashboard" public="true"></dashboard-widget>
</div>
</div>
</div>
</div>
Expand Down

0 comments on commit 2fbf892

Please sign in to comment.