Преглед изворни кода

HUE-7857 [dashboard] Auto resize current widgets when dropping on the same row

Enrico Berti пре 7 година
родитељ
комит
29ffa48

+ 7 - 7
desktop/core/src/desktop/static/desktop/js/gridster-knockout.js

@@ -48,9 +48,9 @@ ko.bindingHandlers.gridster = {
 
       // Update the col and row based on it being added
       if (widget.col === undefined)
-        widget.col = ko.observable(addedWidget.attr('data-col'));
+        widget.col = ko.observable(parseInt(addedWidget.attr('data-col')));
       if (widget.row === undefined)
-        widget.row = ko.observable(addedWidget.attr('data-row'));
+        widget.row = ko.observable(parseInt(addedWidget.attr('data-row')));
 
       // Keep an id for each widget so we can keep our sanity
       if (widget.widgetId === undefined) {
@@ -114,8 +114,8 @@ ko.bindingHandlers.gridster = {
       // Loop through all model items
       for (var i = 0; i < itemsArray.length; i++) {
         var item = itemsArray[i];
-        var eleColValue = $(item.gridsterElement).attr('data-col');
-        var eleRowValue = $(item.gridsterElement).attr('data-row');
+        var eleColValue = parseInt($(item.gridsterElement).attr('data-col'));
+        var eleRowValue = parseInt($(item.gridsterElement).attr('data-row'));
         item.col(eleColValue);
         item.row(eleRowValue);
       }
@@ -124,9 +124,9 @@ ko.bindingHandlers.gridster = {
     // Just in case the consumer set up their own resize handler, we need to chain the calls
     var oldOnResize = gridster.options.resize.stop;
     gridster.options.resize.stop = function (event, ui, $widget) {
-      var widgetId = $widget.attr('data-widgetid');
-      var newSizeX = $widget.attr('data-sizex');
-      var newSizeY = $widget.attr('data-sizey');
+      var widgetId = parseInt($widget.attr('data-widgetid'));
+      var newSizeX = parseInt($widget.attr('data-sizex'));
+      var newSizeY = parseInt($widget.attr('data-sizey'));
 
       var widgetModel = getWidgetModelById(widgetId);
       widgetModel.size_x(newSizeX);

+ 15 - 13
desktop/libs/dashboard/src/dashboard/static/dashboard/js/search.ko.js

@@ -59,10 +59,10 @@ function loadDashboardLayout(viewModel, grister_layout) {
   $.each(grister_layout, function(index, item) {
     viewModel.gridItems.push(
       ko.mapping.fromJS({
-        col: item.col,
-        row: item.row,
-        size_x: item.size_x,
-        size_y: item.size_y,
+        col: parseInt(item.col),
+        row: parseInt(item.row),
+        size_x: parseInt(item.size_x),
+        size_y: parseInt(item.size_y),
         widget: item.widget ? viewModel.getWidgetById(item.widget.id) : null,
         callback: function (el) {
           $('.gridster ul').data('gridster').move_widget(el, 1, 1);
@@ -84,20 +84,20 @@ function layoutToGridster(vm) {
       $.each(row.widgets(), function (indexW, widget) {
         var targetHeight = vm.draggableWidgets[widget.widgetType()].gridsterHeight() || 6;
         layout.push(ko.mapping.fromJS({
-          col: startingCol,
-          row: startingRow,
-          size_x: column.size(),
-          size_y: targetHeight,
+          col: parseInt(startingCol),
+          row: parseInt(startingRow),
+          size_x: parseInt(column.size()),
+          size_y: parseInt(targetHeight),
           widget: vm.getWidgetById(widget.id())
         }));
         startingRow += targetHeight;
       });
       if (row.widgets().length === 0) {
         layout.push(ko.mapping.fromJS({
-          col: startingCol,
-          row: startingRow,
-          size_x: column.size(),
-          size_y: emptyWidgetHeight,
+          col: parseInt(startingCol),
+          row: parseInt(startingRow),
+          size_x: parseInt(column.size()),
+          size_y: parseInt(emptyWidgetHeight),
           widget: null
         }));
         startingRow += emptyWidgetHeight;
@@ -1740,13 +1740,15 @@ var GEO_TYPES = ['SpatialRecursivePrefixTreeFieldType'];
 var RANGE_SELECTABLE_WIDGETS = ['histogram-widget', 'bar-widget', 'line-widget'];
 
 
-var SearchViewModel = function (collection_json, query_json, initial_json) {
+var SearchViewModel = function (collection_json, query_json, initial_json, is_gridster) {
   var self = this;
 
   self.collectionJson = collection_json;
   self.queryJson = query_json;
   self.initialJson = initial_json;
 
+  self.isGridster = !!is_gridster;
+
   self.build = function () {
     self.intervalOptions = ko.observableArray(ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS);
     self.isNested = ko.observable(false);

+ 77 - 13
desktop/libs/dashboard/src/dashboard/templates/common_search.mako

@@ -3666,7 +3666,7 @@ function newSearch() {
 }
 
 function loadSearch(collection, query, initial) {
-  searchViewModel = new SearchViewModel(collection, query, initial);
+  searchViewModel = new SearchViewModel(collection, query, initial, ${ USE_GRIDSTER.get() and 'true' or 'false' });
   ko.applyBindings(searchViewModel, $('#searchComponents')[0]);
 
   searchViewModel.timelineChartTypes = ko.observableArray([
@@ -3853,19 +3853,83 @@ $(document).ready(function () {
       }
       if (dropPosition.row > 0 && dropPosition.col > 0) {
         if (tempDraggable) {
-          searchViewModel.gridItems.push(
-              ko.mapping.fromJS({
-                col: dropPosition.col,
-                row: dropPosition.row,
-                size_x: 6,
-                size_y: tempDraggable.gridsterHeight(),
-                widget: null,
-                callback: function (el) {
-                  showAddFacetDemiModal(tempDraggable, searchViewModel.gridItems()[searchViewModel.gridItems().length - 1]);
-                  tempDraggable = null;
+          var optimalWidgetWidth = 12;
+          var queueLength = 0;
+
+          function decreaseQueue() {
+            queueLength--;
+          }
+
+          function resizeAndMove(widget, width, col) {
+            var $gridster = $(".gridster>ul").data('gridster');
+            queueLength += 2;
+            $gridster.resize_widget($(widget.gridsterElement), width, widget.size_y(), decreaseQueue);
+            widget.size_x(width);
+            $gridster.move_widget($(widget.gridsterElement), col, widget.row(), decreaseQueue);
+            widget.col(col);
+          }
+
+          // automatically resize the width of all the widgets that collide
+          var collindingWidgets = [];
+          searchViewModel.gridItems().forEach(function (existingWidget) {
+            if (existingWidget.row() >= dropPosition.row && existingWidget.row() < dropPosition.row + tempDraggable.gridsterHeight() && !existingWidget.hasBeenTouched) {
+              collindingWidgets.push(existingWidget);
+              var parallelWidgets = [];
+              searchViewModel.gridItems().forEach(function (siblingWidget) {
+                if (siblingWidget.row() >= existingWidget.row() && siblingWidget.row() < existingWidget.row() + existingWidget.size_y() && existingWidget.widgetId() !== siblingWidget.widgetId()) {
+                  siblingWidget.hasBeenTouched = true;
+                  parallelWidgets.push(siblingWidget);
                 }
-              })
-          );
+              });
+              var newOptimalWidth = Math.floor(12 / (parallelWidgets.length + 2)); // 2 is the colliding widget + the dropped widget itself
+              if (newOptimalWidth < optimalWidgetWidth && newOptimalWidth > 0) {
+                var siblings = [];
+                siblings.push(existingWidget);
+                siblings = siblings.concat(parallelWidgets);
+
+                siblings.sort(function (a, b) {
+                  return a.col() > b.col()
+                });
+
+                optimalWidgetWidth = newOptimalWidth;
+
+                // yay for Gridster starting arrays at 1
+                var droppedWidgetFauxColumn = Math.floor((dropPosition.col - 1) / optimalWidgetWidth) + 1;
+                var adjustedDropPosition = (Math.floor((dropPosition.col - 1) / optimalWidgetWidth) * optimalWidgetWidth) + 1;
+                dropPosition.col = adjustedDropPosition;
+
+                var siblingCounter = 0;
+                for (var i = 1; i <= 12 / optimalWidgetWidth; i++) {
+                  if (i !== droppedWidgetFauxColumn) {
+                    resizeAndMove(siblings[siblingCounter], optimalWidgetWidth, ((i - 1) * optimalWidgetWidth) + 1)
+                    siblingCounter++;
+                  }
+                }
+              }
+            }
+          });
+          searchViewModel.gridItems().forEach(function (existingWidget) {
+            existingWidget.hasBeenTouched = false;
+          });
+
+          var canDrop = window.setInterval(function () {
+            if (queueLength === 0) {
+              window.clearInterval(canDrop);
+              searchViewModel.gridItems.push(
+                  ko.mapping.fromJS({
+                    col: dropPosition.col,
+                    row: dropPosition.row,
+                    size_x: optimalWidgetWidth,
+                    size_y: tempDraggable.gridsterHeight(),
+                    widget: null,
+                    callback: function (el) {
+                      showAddFacetDemiModal(tempDraggable, searchViewModel.gridItems()[searchViewModel.gridItems().length - 1]);
+                      tempDraggable = null;
+                    }
+                  })
+              );
+            }
+          }, 100);
         }
         else if (searchViewModel.lastDraggedMeta()) {
           searchViewModel.gridItems.push(