mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
ux: gridstack poc
This commit is contained in:
@@ -7,25 +7,47 @@ 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 gridstack gridstack-handler="ctrl.gridstack" class="grid-stack"
|
||||
options="ctrl.options"
|
||||
on-change="ctrl.onChange(event,items)"
|
||||
on-drag-start="ctrl.onDragStart(event,ui)"
|
||||
on-drag-stop="ctrl.onDragStop(event, ui)"
|
||||
on-resize-start="ctrl.onResizeStart(event, ui)"
|
||||
on-resize-stop="ctrl.onResizeStop(event, ui)">
|
||||
|
||||
<div gridstack-item ng-repeat="panel in ctrl.panels"
|
||||
class="grid-stack-item"
|
||||
gs-item-id="panel.id"
|
||||
gs-item-x="panel.x"
|
||||
gs-item-y="panel.y"
|
||||
gs-item-width="panel.width"
|
||||
gs-item-height="panel.height"
|
||||
gs-item-autopos="1"
|
||||
on-item-added="ctrl.onItemAdded(item)"
|
||||
on-item-removed="ctrl.onItemRemoved(item)">
|
||||
<plugin-component type="panel" class="panel-margin grid-stack-item-content">
|
||||
</plugin-component>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
export function dashGrid() {
|
||||
export class DashGridCtrl {
|
||||
options: any;
|
||||
|
||||
/** @ngInject */
|
||||
constructor(private $rootScope) {
|
||||
this.options = {
|
||||
animate: true,
|
||||
};
|
||||
}
|
||||
|
||||
onResizeStop() {
|
||||
this.$rootScope.$broadcast('render');
|
||||
}
|
||||
}
|
||||
|
||||
export function dashGrid($timeout) {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
@@ -35,10 +57,156 @@ export function dashGrid() {
|
||||
scope: {
|
||||
dashboard: "="
|
||||
},
|
||||
link: function(scope, elem) {
|
||||
$('.grid-stack').gridstack();
|
||||
link: function(scope, elem, attrs, ctrl) {
|
||||
|
||||
ctrl.panels = [];
|
||||
ctrl.dashboard.forEachPanel((panel, panelIndex, row, rowIndex) => {
|
||||
panel.width = 4;
|
||||
panel.height = 4;
|
||||
panel.x = panelIndex * 4;
|
||||
panel.y = rowIndex * 4;
|
||||
ctrl.panels.push(panel);
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.controller('GridstackController', ['$scope', function($scope) {
|
||||
|
||||
var gridstack = null;
|
||||
|
||||
this.init = function(element, options) {
|
||||
gridstack = element.gridstack(options).data('gridstack');
|
||||
return gridstack;
|
||||
};
|
||||
|
||||
this.removeItem = function(element) {
|
||||
if (gridstack) {
|
||||
return gridstack.removeWidget(element, false);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
this.addItem = function(element) {
|
||||
if (gridstack) {
|
||||
gridstack.makeWidget(element);
|
||||
return element;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.directive('gridstack', ['$timeout', function($timeout) {
|
||||
return {
|
||||
restrict: "A",
|
||||
controller: 'GridstackController',
|
||||
scope: {
|
||||
onChange: '&',
|
||||
onDragStart: '&',
|
||||
onDragStop: '&',
|
||||
onResizeStart: '&',
|
||||
onResizeStop: '&',
|
||||
gridstackHandler: '=',
|
||||
options: '='
|
||||
},
|
||||
link: function (scope, element, attrs, controller, ngModel) {
|
||||
|
||||
var gridstack = controller.init(element, scope.options);
|
||||
scope.gridstackHandler = gridstack;
|
||||
|
||||
element.on('change', function (e, items) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onChange({event: e, items: items});
|
||||
});
|
||||
});
|
||||
|
||||
element.on('dragstart', function(e, ui) {
|
||||
scope.onDragStart({event: e, ui: ui});
|
||||
});
|
||||
|
||||
element.on('dragstop', function(e, ui) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onDragStop({event: e, ui: ui});
|
||||
});
|
||||
});
|
||||
|
||||
element.on('resizestart', function(e, ui) {
|
||||
scope.onResizeStart({event: e, ui: ui});
|
||||
});
|
||||
|
||||
element.on('resizestop', function(e, ui) {
|
||||
$timeout(function() {
|
||||
scope.$apply();
|
||||
scope.onResizeStop({event: e, ui: ui});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
/** @ngInject */
|
||||
coreModule.directive('gridstackItem', ['$timeout', function($timeout) {
|
||||
|
||||
return {
|
||||
restrict: "A",
|
||||
controller: 'GridstackController',
|
||||
require: '^gridstack',
|
||||
scope: {
|
||||
gridstackItem: '=',
|
||||
onItemAdded: '&',
|
||||
onItemRemoved: '&',
|
||||
gsItemId: '=',
|
||||
gsItemX: '=',
|
||||
gsItemY: '=',
|
||||
gsItemWidth: '=',
|
||||
gsItemHeight: '=',
|
||||
gsItemAutopos: '='
|
||||
},
|
||||
link: function (scope, element, attrs, controller) {
|
||||
$(element).attr('data-gs-id', scope.gsItemId);
|
||||
$(element).attr('data-gs-x', scope.gsItemX);
|
||||
$(element).attr('data-gs-y', scope.gsItemY);
|
||||
$(element).attr('data-gs-width', scope.gsItemWidth);
|
||||
$(element).attr('data-gs-height', scope.gsItemHeight);
|
||||
$(element).attr('data-gs-auto-position', scope.gsItemAutopos);
|
||||
var widget = controller.addItem(element);
|
||||
var item = element.data('_gridstack_node');
|
||||
$timeout(function() {
|
||||
scope.onItemAdded({item: item});
|
||||
});
|
||||
scope.$watch(function () { return $(element).attr('data-gs-id'); }, function (val) {
|
||||
scope.gsItemId = val;
|
||||
});
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-x'); }, function(val) {
|
||||
scope.gsItemX = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-y'); }, function(val) {
|
||||
scope.gsItemY = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-width'); }, function(val) {
|
||||
scope.gsItemWidth = val;
|
||||
});
|
||||
|
||||
scope.$watch(function(){ return $(element).attr('data-gs-height'); }, function(val) {
|
||||
scope.gsItemHeight = val;
|
||||
});
|
||||
|
||||
element.bind('$destroy', function() {
|
||||
var item = element.data('_gridstack_node');
|
||||
scope.onItemRemoved({item: item});
|
||||
controller.removeItem(element);
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
coreModule.directive('dashGrid', dashGrid);
|
||||
|
@@ -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';
|
||||
import {dashGrid} from './components/dashgrid/dashgrid';
|
||||
|
||||
export {
|
||||
arrayJoin,
|
||||
@@ -72,5 +72,5 @@ export {
|
||||
helpModal,
|
||||
NavModelSrv,
|
||||
NavModel,
|
||||
DashGridCtrl,
|
||||
dashGrid,
|
||||
};
|
||||
|
@@ -160,18 +160,19 @@ export class PanelCtrl {
|
||||
}
|
||||
|
||||
calculatePanelHeight() {
|
||||
if (this.fullscreen) {
|
||||
var docHeight = $(window).height();
|
||||
var editHeight = Math.floor(docHeight * 0.4);
|
||||
var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
||||
} else {
|
||||
this.containerHeight = this.panel.height || this.row.height;
|
||||
if (_.isString(this.containerHeight)) {
|
||||
this.containerHeight = parseInt(this.containerHeight.replace('px', ''), 10);
|
||||
}
|
||||
}
|
||||
|
||||
// if (this.fullscreen) {
|
||||
// var docHeight = $(window).height();
|
||||
// var editHeight = Math.floor(docHeight * 0.4);
|
||||
// var fullscreenHeight = Math.floor(docHeight * 0.8);
|
||||
// this.containerHeight = this.editMode ? editHeight : fullscreenHeight;
|
||||
// } else {
|
||||
// this.containerHeight = this.panel.height || this.row.height;
|
||||
// if (_.isString(this.containerHeight)) {
|
||||
// this.containerHeight = parseInt(this.containerHeight.replace('px', ''), 10);
|
||||
// }
|
||||
// }
|
||||
const rowSpan = this.panel.height || 4;
|
||||
this.containerHeight = rowSpan * 60 + ((rowSpan-1) * 20);
|
||||
this.height = this.containerHeight - (PANEL_BORDER + PANEL_PADDING + (this.panel.title ? TITLE_HEIGHT : EMPTY_TITLE_HEIGHT));
|
||||
}
|
||||
|
||||
|
@@ -26,7 +26,6 @@ var panelTemplate = `
|
||||
<div class="panel-content">
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
||||
<panel-resizer></panel-resizer>
|
||||
</div>
|
||||
|
||||
<div class="panel-full-edit" ng-if="ctrl.editMode">
|
||||
|
@@ -1,10 +1,8 @@
|
||||
define([
|
||||
'angular',
|
||||
'jquery',
|
||||
'lodash',
|
||||
'tether',
|
||||
],
|
||||
function (angular, $, _, Tether) {
|
||||
function (angular, $) {
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
@@ -17,139 +15,96 @@ function (angular, $, _, Tether) {
|
||||
'<span class="panel-time-info" ng-show="ctrl.timeInfo"><i class="fa fa-clock-o"></i> {{ctrl.timeInfo}}</span>' +
|
||||
'</span>';
|
||||
|
||||
function createMenuTemplate(ctrl) {
|
||||
var template = '<div class="panel-menu small">';
|
||||
|
||||
if (ctrl.dashboard.meta.canEdit) {
|
||||
template += '<div class="panel-menu-inner">';
|
||||
template += '<div class="panel-menu-row">';
|
||||
if (!ctrl.dashboard.meta.fullscreen) {
|
||||
template += '<a class="panel-menu-icon pull-left" ng-click="ctrl.updateColumnSpan(-1)"><i class="fa fa-minus"></i></a>';
|
||||
template += '<a class="panel-menu-icon pull-left" ng-click="ctrl.updateColumnSpan(1)"><i class="fa fa-plus"></i></a>';
|
||||
}
|
||||
template += '<a class="panel-menu-icon pull-right" ng-click="ctrl.removePanel()"><i class="fa fa-trash"></i></a>';
|
||||
template += '<div class="clearfix"></div>';
|
||||
template += '</div>';
|
||||
}
|
||||
|
||||
template += '<div class="panel-menu-row">';
|
||||
template += '<a class="panel-menu-link" gf-dropdown="extendedMenu"><i class="fa fa-bars"></i></a>';
|
||||
|
||||
_.each(ctrl.getMenu(), function(item) {
|
||||
// skip edit actions if not editor
|
||||
if (item.role === 'Editor' && !ctrl.dashboard.meta.canEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
template += '<a class="panel-menu-link" ';
|
||||
if (item.click) { template += ' ng-click="' + item.click + '"'; }
|
||||
if (item.href) { template += ' href="' + item.href + '"'; }
|
||||
template += '>';
|
||||
template += item.text + '</a>';
|
||||
});
|
||||
|
||||
template += '</div>';
|
||||
template += '</div>';
|
||||
template += '</div>';
|
||||
return template;
|
||||
}
|
||||
|
||||
function getExtendedMenu(ctrl) {
|
||||
return ctrl.getExtendedMenu();
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, elem) {
|
||||
var $link = $(linkTemplate);
|
||||
var $panelContainer = elem.parents(".panel-container");
|
||||
var menuScope = null;
|
||||
var ctrl = $scope.ctrl;
|
||||
var timeout = null;
|
||||
var $menu = null;
|
||||
var teather;
|
||||
//var menuScope = null;
|
||||
//var timeout = null;
|
||||
//var $menu = null;
|
||||
//var teather;
|
||||
|
||||
elem.append($link);
|
||||
|
||||
function dismiss(time, force) {
|
||||
clearTimeout(timeout);
|
||||
timeout = null;
|
||||
// function dismiss(time, force) {
|
||||
// clearTimeout(timeout);
|
||||
// timeout = null;
|
||||
//
|
||||
// if (time) {
|
||||
// timeout = setTimeout(dismiss, time);
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // if hovering or draging pospone close
|
||||
// if (force !== true) {
|
||||
// if ($menu.is(':hover') || $scope.ctrl.dashboard.$$panelDragging) {
|
||||
// dismiss(2200);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (menuScope) {
|
||||
// teather.destroy();
|
||||
// $menu.unbind();
|
||||
// $menu.remove();
|
||||
// menuScope.$destroy();
|
||||
// menuScope = null;
|
||||
// $menu = null;
|
||||
// $panelContainer.removeClass('panel-highlight');
|
||||
// }
|
||||
// }
|
||||
|
||||
if (time) {
|
||||
timeout = setTimeout(dismiss, time);
|
||||
return;
|
||||
}
|
||||
|
||||
// if hovering or draging pospone close
|
||||
if (force !== true) {
|
||||
if ($menu.is(':hover') || $scope.ctrl.dashboard.$$panelDragging) {
|
||||
dismiss(2200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (menuScope) {
|
||||
teather.destroy();
|
||||
$menu.unbind();
|
||||
$menu.remove();
|
||||
menuScope.$destroy();
|
||||
menuScope = null;
|
||||
$menu = null;
|
||||
$panelContainer.removeClass('panel-highlight');
|
||||
}
|
||||
}
|
||||
|
||||
var showMenu = function(e) {
|
||||
// if menu item is clicked and menu was just removed from dom ignore this event
|
||||
if (!$.contains(document, e.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($menu) {
|
||||
dismiss();
|
||||
return;
|
||||
}
|
||||
|
||||
var menuTemplate;
|
||||
menuTemplate = createMenuTemplate(ctrl);
|
||||
|
||||
$menu = $(menuTemplate);
|
||||
$menu.mouseleave(function() {
|
||||
dismiss(1000);
|
||||
});
|
||||
|
||||
menuScope = $scope.$new();
|
||||
menuScope.extendedMenu = getExtendedMenu(ctrl);
|
||||
menuScope.dismiss = function() {
|
||||
dismiss(null, true);
|
||||
};
|
||||
|
||||
$(".panel-container").removeClass('panel-highlight');
|
||||
$panelContainer.toggleClass('panel-highlight');
|
||||
|
||||
$('.panel-menu').remove();
|
||||
|
||||
elem.append($menu);
|
||||
|
||||
$scope.$apply(function() {
|
||||
$compile($menu.contents())(menuScope);
|
||||
|
||||
teather = new Tether({
|
||||
element: $menu,
|
||||
target: $panelContainer,
|
||||
attachment: 'bottom center',
|
||||
targetAttachment: 'top center',
|
||||
constraints: [
|
||||
{
|
||||
to: 'window',
|
||||
attachment: 'together',
|
||||
pin: true
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
dismiss(2200);
|
||||
var showMenu = function() {
|
||||
// // if menu item is clicked and menu was just removed from dom ignore this event
|
||||
// if (!$.contains(document, e.target)) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if ($menu) {
|
||||
// dismiss();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// var menuTemplate;
|
||||
// menuTemplate = createMenuTemplate(ctrl);
|
||||
//
|
||||
// $menu = $(menuTemplate);
|
||||
// $menu.mouseleave(function() {
|
||||
// dismiss(1000);
|
||||
// });
|
||||
//
|
||||
// menuScope = $scope.$new();
|
||||
// menuScope.extendedMenu = getExtendedMenu(ctrl);
|
||||
// menuScope.dismiss = function() {
|
||||
// dismiss(null, true);
|
||||
// };
|
||||
//
|
||||
// $(".panel-container").removeClass('panel-highlight');
|
||||
// $panelContainer.toggleClass('panel-highlight');
|
||||
//
|
||||
// $('.panel-menu').remove();
|
||||
//
|
||||
// elem.append($menu);
|
||||
//
|
||||
// $scope.$apply(function() {
|
||||
// $compile($menu.contents())(menuScope);
|
||||
//
|
||||
// teather = new Tether({
|
||||
// element: $menu,
|
||||
// target: $panelContainer,
|
||||
// attachment: 'bottom center',
|
||||
// targetAttachment: 'top center',
|
||||
// constraints: [
|
||||
// {
|
||||
// to: 'window',
|
||||
// attachment: 'together',
|
||||
// pin: true
|
||||
// }
|
||||
// ]
|
||||
// });
|
||||
// });
|
||||
//
|
||||
// dismiss(2200);
|
||||
};
|
||||
|
||||
elem.click(showMenu);
|
||||
|
1
public/app/headers/common.d.ts
vendored
1
public/app/headers/common.d.ts
vendored
@@ -77,3 +77,4 @@ declare module 'gridstack' {
|
||||
var gridstack: any;
|
||||
export default gridstack;
|
||||
}
|
||||
|
||||
|
@@ -33,30 +33,9 @@ System.config({
|
||||
"jquery.flot.gauge": "vendor/flot/jquery.flot.gauge",
|
||||
"d3": "vendor/d3/d3.js",
|
||||
"jquery.flot.dashes": "vendor/flot/jquery.flot.dashes",
|
||||
"jquery-ui": "vendor/npm/jquery-ui-dist/jquery-ui.js",
|
||||
"jquery-ui": "vendor/jquery-ui/custom.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: {
|
||||
@@ -85,12 +64,12 @@ System.config({
|
||||
deps: ['jquery'],
|
||||
},
|
||||
'vendor/npm/gridstack/dist/gridstack.js': {
|
||||
format: 'amd',
|
||||
format: 'global',
|
||||
deps: ['jquery', 'jquery-ui', 'lodash'],
|
||||
},
|
||||
"vendor/npm/gridstack/dist/gridstack.jQueryUI.js": {
|
||||
format: 'amd',
|
||||
deps: ['gridstack.jquery-ui'],
|
||||
format: 'global',
|
||||
deps: ['gridstack'],
|
||||
},
|
||||
'vendor/npm/virtual-scroll/src/indx.js': {
|
||||
format: 'cjs',
|
||||
|
@@ -76,6 +76,7 @@
|
||||
@import "components/edit_sidemenu.scss";
|
||||
@import "components/row.scss";
|
||||
@import "components/gridstack.scss";
|
||||
@import "components/griddash.scss";
|
||||
|
||||
// PAGES
|
||||
@import "pages/login";
|
||||
|
2
public/sass/components/_griddash.scss
Normal file
2
public/sass/components/_griddash.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
.grid-stack-item-content {
|
||||
}
|
@@ -20,8 +20,8 @@ div.flot-text {
|
||||
}
|
||||
|
||||
.panel {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
//display: inline-block;
|
||||
//float: left;
|
||||
|
||||
&--solo {
|
||||
.resize-panel-handle {
|
||||
@@ -35,7 +35,7 @@ div.flot-text {
|
||||
|
||||
.panel-margin {
|
||||
margin: 0 0.4rem 0.8rem 0.4rem;
|
||||
display: block;
|
||||
//display: block;
|
||||
}
|
||||
|
||||
.panel-container {
|
||||
|
4034
public/vendor/jquery-ui/custom.js
vendored
Normal file
4034
public/vendor/jquery-ui/custom.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user