Quellcode durchsuchen

Gridstack: testing

Torkel Ödegaard vor 8 Jahren
Ursprung
Commit
35c440eb79

+ 2 - 0
package.json

@@ -65,9 +65,11 @@
   "dependencies": {
     "eventemitter3": "^2.0.2",
     "gaze": "^1.1.2",
+    "gridstack": "^0.3.0",
     "grunt-jscs": "3.0.1",
     "grunt-sass-lint": "^0.2.2",
     "grunt-sync": "^0.6.2",
+    "jquery-ui-dist": "^1.12.1",
     "karma-sinon": "^1.0.5",
     "lodash": "^4.17.2",
     "mousetrap": "^1.6.0",

+ 44 - 0
public/app/core/components/dashgrid/dashgrid.ts

@@ -0,0 +1,44 @@
+///<reference path="../../../headers/common.d.ts" />
+
+import $ from 'jquery';
+import coreModule from '../../core_module';
+
+import 'jquery-ui';
+import 'gridstack';
+import 'gridstack.jquery-ui';
+
+export class DashGridCtrl {
+}
+
+const template = `
+<div class="grid-stack">
+    <div class="grid-stack-item"
+        data-gs-x="0" data-gs-y="0"
+        data-gs-width="4" data-gs-height="2">
+            <div class="grid-stack-item-content"></div>
+    </div>
+    <div class="grid-stack-item"
+        data-gs-x="4" data-gs-y="0"
+        data-gs-width="4" data-gs-height="4">
+            <div class="grid-stack-item-content"></div>
+    </div>
+</div>
+`;
+
+export function dashGrid() {
+  return {
+    restrict: 'E',
+    template: template,
+    controller: DashGridCtrl,
+    bindToController: true,
+    controllerAs: 'ctrl',
+    scope: {
+      dashboard: "="
+    },
+    link: function(scope, elem) {
+      $('.grid-stack').gridstack();
+    }
+  };
+}
+
+coreModule.directive('dashGrid', dashGrid);

+ 2 - 1
public/app/core/core.ts

@@ -46,7 +46,7 @@ import {contextSrv} from './services/context_srv';
 import {KeybindingSrv} from './services/keybindingSrv';
 import {helpModal} from './components/help/help';
 import {NavModelSrv, NavModel} from './nav_model_srv';
-
+import {DashGridCtrl} from './components/dashgrid/dashgrid';
 
 export {
   arrayJoin,
@@ -72,4 +72,5 @@ export {
   helpModal,
   NavModelSrv,
   NavModel,
+  DashGridCtrl,
 };

+ 4 - 0
public/app/headers/common.d.ts

@@ -73,3 +73,7 @@ declare module 'd3' {
   export default d3;
 }
 
+declare module 'gridstack' {
+  var gridstack: any;
+  export default gridstack;
+}

+ 3 - 2
public/app/partials/dashboard.html

@@ -9,8 +9,9 @@
 
 		<div class="clearfix"></div>
 
-    <dash-row class="dash-row" ng-repeat="row in dashboard.rows" row="row" dashboard="dashboard">
-    </dash-row>
+		<dash-grid dashboard="dashboard">
+
+		</dash-grid>
 
     <div ng-show='dashboard.meta.canEdit && !dashboard.meta.fullscreen' class="add-row-panel-hint">
       <div class="span12" style="text-align:left;">

+ 38 - 2
public/app/system.conf.js

@@ -32,7 +32,31 @@ System.config({
     "jquery.flot.fillbelow": "vendor/flot/jquery.flot.fillbelow",
     "jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
     "d3": "vendor/d3/d3.js",
-    "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes"
+    "jquery.flot.dashes": "vendor/flot/jquery.flot.dashes",
+    "jquery-ui": "vendor/npm/jquery-ui-dist/jquery-ui.js",
+    "gridstack": "vendor/npm/gridstack/dist/gridstack.js",
+    "gridstack.jquery-ui": "vendor/npm/gridstack/dist/gridstack.jQueryUI.js",
+
+    'jquery-ui/data': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/disable-selection': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/focusable': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/form': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/ie': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/keycode': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/labels': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/jquery-1-7': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/plugin': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/safe-active-element': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/safe-blur': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/scroll-parent': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/tabbable': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/unique-id': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/version': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/widget': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/widgets/mouse': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/widgets/draggable': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/widgets/droppable': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
+    'jquery-ui/widgets/resizable': 'vendor/npm/jquery-ui-dist/jquery-ui.js',
   },
 
   packages: {
@@ -52,10 +76,22 @@ System.config({
 
   map: {
     text: 'vendor/plugin-text/text.js',
-    css: 'app/core/utils/css_loader.js'
+    css: 'app/core/utils/css_loader.js',
   },
 
   meta: {
+    'vendor/npm/jquery-ui/jquery-ui.js': {
+      format: 'amd',
+      deps: ['jquery'],
+    },
+    'vendor/npm/gridstack/dist/gridstack.js': {
+      format: 'amd',
+      deps: ['jquery', 'jquery-ui', 'lodash'],
+    },
+    "vendor/npm/gridstack/dist/gridstack.jQueryUI.js": {
+      format: 'amd',
+      deps: ['gridstack.jquery-ui'],
+    },
     'vendor/npm/virtual-scroll/src/indx.js': {
       format: 'cjs',
       exports: 'VirtualScroll',

+ 1 - 0
public/sass/_grafana.scss

@@ -75,6 +75,7 @@
 @import "components/jsontree";
 @import "components/edit_sidemenu.scss";
 @import "components/row.scss";
+@import "components/gridstack.scss";
 
 // PAGES
 @import "pages/login";

+ 387 - 0
public/sass/components/_gridstack.scss

@@ -0,0 +1,387 @@
+:root .grid-stack-item > .ui-resizable-handle {
+  filter: none;
+}
+
+.grid-stack {
+  position: relative;
+}
+
+.grid-stack.grid-stack-rtl {
+  direction: ltr;
+}
+
+.grid-stack.grid-stack-rtl > .grid-stack-item {
+  direction: rtl;
+}
+
+.grid-stack .grid-stack-placeholder > .placeholder-content {
+  border: 1px dashed lightgray;
+  margin: 0;
+  position: absolute;
+  top: 0;
+  left: 10px;
+  right: 10px;
+  bottom: 0;
+  width: auto;
+  z-index: 0 !important;
+  text-align: center;
+}
+
+.grid-stack > .grid-stack-item {
+  min-width: 8.3333333333%;
+  position: absolute;
+  padding: 0;
+}
+
+.grid-stack > .grid-stack-item > .grid-stack-item-content {
+  margin: 0;
+  position: absolute;
+  top: 0;
+  left: 10px;
+  right: 10px;
+  bottom: 0;
+  width: auto;
+  z-index: 0 !important;
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-handle {
+  position: absolute;
+  font-size: 0.1px;
+  display: block;
+  -ms-touch-action: none;
+  touch-action: none;
+}
+
+.grid-stack > .grid-stack-item.ui-resizable-disabled > .ui-resizable-handle,
+.grid-stack > .grid-stack-item.ui-resizable-autohide > .ui-resizable-handle {
+  display: none;
+}
+
+.grid-stack > .grid-stack-item.ui-draggable-dragging, .grid-stack > .grid-stack-item.ui-resizable-resizing {
+  z-index: 100;
+}
+
+.grid-stack > .grid-stack-item.ui-draggable-dragging > .grid-stack-item-content,
+.grid-stack > .grid-stack-item.ui-draggable-dragging > .grid-stack-item-content, .grid-stack > .grid-stack-item.ui-resizable-resizing > .grid-stack-item-content,
+.grid-stack > .grid-stack-item.ui-resizable-resizing > .grid-stack-item-content {
+  box-shadow: 1px 4px 6px rgba(0, 0, 0, 0.2);
+  opacity: 0.8;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-se,
+.grid-stack > .grid-stack-item > .ui-resizable-sw {
+  background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTYuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIgdmlld0JveD0iMCAwIDUxMS42MjYgNTExLjYyNyIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNTExLjYyNiA1MTEuNjI3OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+CjxnPgoJPHBhdGggZD0iTTMyOC45MDYsNDAxLjk5NGgtMzYuNTUzVjEwOS42MzZoMzYuNTUzYzQuOTQ4LDAsOS4yMzYtMS44MDksMTIuODQ3LTUuNDI2YzMuNjEzLTMuNjE1LDUuNDIxLTcuODk4LDUuNDIxLTEyLjg0NSAgIGMwLTQuOTQ5LTEuODAxLTkuMjMxLTUuNDI4LTEyLjg1MWwtNzMuMDg3LTczLjA5QzI2NS4wNDQsMS44MDksMjYwLjc2LDAsMjU1LjgxMywwYy00Ljk0OCwwLTkuMjI5LDEuODA5LTEyLjg0Nyw1LjQyNCAgIGwtNzMuMDg4LDczLjA5Yy0zLjYxOCwzLjYxOS01LjQyNCw3LjkwMi01LjQyNCwxMi44NTFjMCw0Ljk0NiwxLjgwNyw5LjIyOSw1LjQyNCwxMi44NDVjMy42MTksMy42MTcsNy45MDEsNS40MjYsMTIuODUsNS40MjYgICBoMzYuNTQ1djI5Mi4zNThoLTM2LjU0MmMtNC45NTIsMC05LjIzNSwxLjgwOC0xMi44NSw1LjQyMWMtMy42MTcsMy42MjEtNS40MjQsNy45MDUtNS40MjQsMTIuODU0ICAgYzAsNC45NDUsMS44MDcsOS4yMjcsNS40MjQsMTIuODQ3bDczLjA4OSw3My4wODhjMy42MTcsMy42MTcsNy44OTgsNS40MjQsMTIuODQ3LDUuNDI0YzQuOTUsMCw5LjIzNC0xLjgwNywxMi44NDktNS40MjQgICBsNzMuMDg3LTczLjA4OGMzLjYxMy0zLjYyLDUuNDIxLTcuOTAxLDUuNDIxLTEyLjg0N2MwLTQuOTQ4LTEuODA4LTkuMjMyLTUuNDIxLTEyLjg1NCAgIEMzMzguMTQyLDQwMy44MDIsMzMzLjg1Nyw0MDEuOTk0LDMyOC45MDYsNDAxLjk5NHoiIGZpbGw9IiM2NjY2NjYiLz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8Zz4KPC9nPgo8L3N2Zz4K);
+  background-repeat: no-repeat;
+  background-position: center;
+  -webkit-transform: rotate(45deg);
+  -moz-transform: rotate(45deg);
+  -ms-transform: rotate(45deg);
+  -o-transform: rotate(45deg);
+  transform: rotate(45deg);
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-se {
+  -webkit-transform: rotate(-45deg);
+  -moz-transform: rotate(-45deg);
+  -ms-transform: rotate(-45deg);
+  -o-transform: rotate(-45deg);
+  transform: rotate(-45deg);
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-nw {
+  cursor: nw-resize;
+  width: 20px;
+  height: 20px;
+  left: 10px;
+  top: 0;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-n {
+  cursor: n-resize;
+  height: 10px;
+  top: 0;
+  left: 25px;
+  right: 25px;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-ne {
+  cursor: ne-resize;
+  width: 20px;
+  height: 20px;
+  right: 10px;
+  top: 0;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-e {
+  cursor: e-resize;
+  width: 10px;
+  right: 10px;
+  top: 15px;
+  bottom: 15px;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-se {
+  cursor: se-resize;
+  width: 20px;
+  height: 20px;
+  right: 10px;
+  bottom: 0;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-s {
+  cursor: s-resize;
+  height: 10px;
+  left: 25px;
+  bottom: 0;
+  right: 25px;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-sw {
+  cursor: sw-resize;
+  width: 20px;
+  height: 20px;
+  left: 10px;
+  bottom: 0;
+}
+
+.grid-stack > .grid-stack-item > .ui-resizable-w {
+  cursor: w-resize;
+  width: 10px;
+  left: 10px;
+  top: 15px;
+  bottom: 15px;
+}
+
+.grid-stack > .grid-stack-item.ui-draggable-dragging > .ui-resizable-handle {
+  display: none !important;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='1'] {
+  width: 8.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='1'] {
+  left: 8.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='1'] {
+  min-width: 8.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='1'] {
+  max-width: 8.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='2'] {
+  width: 16.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='2'] {
+  left: 16.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='2'] {
+  min-width: 16.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='2'] {
+  max-width: 16.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='3'] {
+  width: 25%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='3'] {
+  left: 25%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='3'] {
+  min-width: 25%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='3'] {
+  max-width: 25%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='4'] {
+  width: 33.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='4'] {
+  left: 33.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='4'] {
+  min-width: 33.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='4'] {
+  max-width: 33.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='5'] {
+  width: 41.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='5'] {
+  left: 41.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='5'] {
+  min-width: 41.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='5'] {
+  max-width: 41.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='6'] {
+  width: 50%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='6'] {
+  left: 50%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='6'] {
+  min-width: 50%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='6'] {
+  max-width: 50%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='7'] {
+  width: 58.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='7'] {
+  left: 58.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='7'] {
+  min-width: 58.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='7'] {
+  max-width: 58.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='8'] {
+  width: 66.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='8'] {
+  left: 66.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='8'] {
+  min-width: 66.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='8'] {
+  max-width: 66.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='9'] {
+  width: 75%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='9'] {
+  left: 75%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='9'] {
+  min-width: 75%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='9'] {
+  max-width: 75%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='10'] {
+  width: 83.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='10'] {
+  left: 83.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='10'] {
+  min-width: 83.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='10'] {
+  max-width: 83.3333333333%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='11'] {
+  width: 91.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='11'] {
+  left: 91.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='11'] {
+  min-width: 91.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='11'] {
+  max-width: 91.6666666667%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-width='12'] {
+  width: 100%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-x='12'] {
+  left: 100%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-min-width='12'] {
+  min-width: 100%;
+}
+
+.grid-stack > .grid-stack-item[data-gs-max-width='12'] {
+  max-width: 100%;
+}
+
+.grid-stack.grid-stack-animate,
+.grid-stack.grid-stack-animate .grid-stack-item {
+  -webkit-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s;
+  -moz-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s;
+  -ms-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s;
+  -o-transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s;
+  transition: left 0.3s, top 0.3s, height 0.3s, width 0.3s;
+}
+
+.grid-stack.grid-stack-animate .grid-stack-item.ui-draggable-dragging,
+.grid-stack.grid-stack-animate .grid-stack-item.ui-resizable-resizing,
+.grid-stack.grid-stack-animate .grid-stack-item.grid-stack-placeholder {
+  -webkit-transition: left 0s, top 0s, height 0s, width 0s;
+  -moz-transition: left 0s, top 0s, height 0s, width 0s;
+  -ms-transition: left 0s, top 0s, height 0s, width 0s;
+  -o-transition: left 0s, top 0s, height 0s, width 0s;
+  transition: left 0s, top 0s, height 0s, width 0s;
+}
+
+.grid-stack.grid-stack-one-column-mode {
+  height: auto !important;
+}
+
+.grid-stack.grid-stack-one-column-mode > .grid-stack-item {
+  position: relative !important;
+  width: auto !important;
+  left: 0 !important;
+  top: auto !important;
+  margin-bottom: 20px;
+  max-width: none !important;
+}
+
+.grid-stack.grid-stack-one-column-mode > .grid-stack-item > .ui-resizable-handle {
+  display: none;
+}

+ 2 - 0
tasks/options/copy.js

@@ -34,6 +34,8 @@ module.exports = function(config) {
         'remarkable/dist/*',
         'virtual-scroll/**/*',
         'mousetrap/**/*',
+        'gridstack/dist/*',
+        'jquery-ui-dist/*',
       ],
       dest: '<%= srcDir %>/vendor/npm'
     }

+ 28 - 8
yarn.lock

@@ -1663,9 +1663,9 @@ glob@7.0.5:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.0.0:
-  version "7.0.6"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
+glob@^7.0.0, glob@^7.1.1, glob@~7.1.1:
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
   dependencies:
     fs.realpath "^1.0.0"
     inflight "^1.0.4"
@@ -1674,9 +1674,9 @@ glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@~7.0.0:
     once "^1.3.0"
     path-is-absolute "^1.0.0"
 
-glob@^7.1.1, glob@~7.1.1:
-  version "7.1.1"
-  resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
+glob@^7.0.3, glob@^7.0.5, glob@~7.0.0:
+  version "7.0.6"
+  resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a"
   dependencies:
     fs.realpath "^1.0.0"
     inflight "^1.0.4"
@@ -1741,6 +1741,14 @@ graceful-fs@~1.2.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
 
+gridstack@^0.3.0:
+  version "0.3.0"
+  resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-0.3.0.tgz#be1c7891f3fbd2af60f9d60f4c7d517a30d3bb78"
+  dependencies:
+    jquery "^3.1.0"
+    jquery-ui "^1.12.0"
+    lodash "^4.14.2"
+
 growl@1.9.2:
   version "1.9.2"
   resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
@@ -2451,6 +2459,18 @@ jodid25519@^1.0.0:
   dependencies:
     jsbn "~0.1.0"
 
+jquery-ui-dist@^1.12.1:
+  version "1.12.1"
+  resolved "https://registry.yarnpkg.com/jquery-ui-dist/-/jquery-ui-dist-1.12.1.tgz#5c0815d3cc6f90ff5faaf5b268a6e23b4ca904fa"
+
+jquery-ui@^1.12.0:
+  version "1.12.1"
+  resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.12.1.tgz#bcb4045c8dd0539c134bc1488cdd3e768a7a9e51"
+
+jquery@^3.1.0:
+  version "3.2.1"
+  resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.2.1.tgz#5c4d9de652af6cd0a770154a631bba12b015c787"
+
 js-base64@^2.1.9:
   version "2.1.9"
   resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.1.9.tgz#f0e80ae039a4bd654b5f281fc93f04a914a7fcce"
@@ -3807,11 +3827,11 @@ resolve-pkg@^0.1.0:
   dependencies:
     resolve-from "^2.0.0"
 
-resolve@1.1.x, resolve@^1.1.6, resolve@~1.1.0:
+resolve@1.1.x, resolve@~1.1.0:
   version "1.1.7"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
 
-resolve@^1.3.2:
+resolve@^1.1.6, resolve@^1.3.2:
   version "1.3.3"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
   dependencies: