624 lines
92 KiB
JavaScript
624 lines
92 KiB
JavaScript
|
import { NgForOf, NgStyle } from '@angular/common';
|
||
|
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, NgZone, Renderer2, ViewEncapsulation } from '@angular/core';
|
||
|
import { debounceTime, Subject, switchMap, takeUntil, timer } from 'rxjs';
|
||
|
import { GridsterCompact } from './gridsterCompact.service';
|
||
|
import { GridsterConfigService } from './gridsterConfig.constant';
|
||
|
import { GridType } from './gridsterConfig.interface';
|
||
|
import { GridsterEmptyCell } from './gridsterEmptyCell.service';
|
||
|
import { GridsterPreviewComponent } from './gridsterPreview.component';
|
||
|
import { GridsterRenderer } from './gridsterRenderer.service';
|
||
|
import { GridsterUtils } from './gridsterUtils.service';
|
||
|
import * as i0 from "@angular/core";
|
||
|
class GridsterComponent {
|
||
|
constructor(el, renderer, cdRef, zone) {
|
||
|
this.renderer = renderer;
|
||
|
this.cdRef = cdRef;
|
||
|
this.zone = zone;
|
||
|
this.columns = 0;
|
||
|
this.rows = 0;
|
||
|
this.gridColumns = [];
|
||
|
this.gridRows = [];
|
||
|
this.previewStyle$ = new EventEmitter();
|
||
|
this.calculateLayout$ = new Subject();
|
||
|
this.resize$ = new Subject();
|
||
|
this.destroy$ = new Subject();
|
||
|
this.optionsChanged = () => {
|
||
|
this.setOptions();
|
||
|
let widgetsIndex = this.grid.length - 1;
|
||
|
let widget;
|
||
|
for (; widgetsIndex >= 0; widgetsIndex--) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
widget.updateOptions();
|
||
|
}
|
||
|
this.calculateLayout();
|
||
|
};
|
||
|
this.onResize = () => {
|
||
|
if (this.el.clientWidth) {
|
||
|
if (this.options.setGridSize) {
|
||
|
// reset width/height so the size is recalculated afterwards
|
||
|
this.renderer.setStyle(this.el, 'width', '');
|
||
|
this.renderer.setStyle(this.el, 'height', '');
|
||
|
}
|
||
|
this.setGridSize();
|
||
|
this.calculateLayout();
|
||
|
}
|
||
|
};
|
||
|
this.getNextPossiblePosition = (newItem, startingFrom = {}) => {
|
||
|
if (newItem.cols === -1) {
|
||
|
newItem.cols = this.$options.defaultItemCols;
|
||
|
}
|
||
|
if (newItem.rows === -1) {
|
||
|
newItem.rows = this.$options.defaultItemRows;
|
||
|
}
|
||
|
this.setGridDimensions();
|
||
|
let rowsIndex = startingFrom.y || 0;
|
||
|
let colsIndex;
|
||
|
for (; rowsIndex < this.rows; rowsIndex++) {
|
||
|
newItem.y = rowsIndex;
|
||
|
colsIndex = startingFrom.x || 0;
|
||
|
for (; colsIndex < this.columns; colsIndex++) {
|
||
|
newItem.x = colsIndex;
|
||
|
if (!this.checkCollision(newItem)) {
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
const canAddToRows = this.$options.maxRows >= this.rows + newItem.rows;
|
||
|
const canAddToColumns = this.$options.maxCols >= this.columns + newItem.cols;
|
||
|
const addToRows = this.rows <= this.columns && canAddToRows;
|
||
|
if (!addToRows && canAddToColumns) {
|
||
|
newItem.x = this.columns;
|
||
|
newItem.y = 0;
|
||
|
return true;
|
||
|
}
|
||
|
else if (canAddToRows) {
|
||
|
newItem.y = this.rows;
|
||
|
newItem.x = 0;
|
||
|
return true;
|
||
|
}
|
||
|
return false;
|
||
|
};
|
||
|
this.getFirstPossiblePosition = (item) => {
|
||
|
const tmpItem = Object.assign({}, item);
|
||
|
this.getNextPossiblePosition(tmpItem);
|
||
|
return tmpItem;
|
||
|
};
|
||
|
this.getLastPossiblePosition = (item) => {
|
||
|
let farthestItem = { y: 0, x: 0 };
|
||
|
farthestItem = this.grid.reduce((prev, curr) => {
|
||
|
const currCoords = {
|
||
|
y: curr.$item.y + curr.$item.rows - 1,
|
||
|
x: curr.$item.x + curr.$item.cols - 1
|
||
|
};
|
||
|
if (GridsterUtils.compareItems(prev, currCoords) === 1) {
|
||
|
return currCoords;
|
||
|
}
|
||
|
else {
|
||
|
return prev;
|
||
|
}
|
||
|
}, farthestItem);
|
||
|
const tmpItem = Object.assign({}, item);
|
||
|
this.getNextPossiblePosition(tmpItem, farthestItem);
|
||
|
return tmpItem;
|
||
|
};
|
||
|
this.el = el.nativeElement;
|
||
|
this.$options = JSON.parse(JSON.stringify(GridsterConfigService));
|
||
|
this.mobile = false;
|
||
|
this.curWidth = 0;
|
||
|
this.curHeight = 0;
|
||
|
this.grid = [];
|
||
|
this.curColWidth = 0;
|
||
|
this.curRowHeight = 0;
|
||
|
this.dragInProgress = false;
|
||
|
this.emptyCell = new GridsterEmptyCell(this);
|
||
|
this.compact = new GridsterCompact(this);
|
||
|
this.gridRenderer = new GridsterRenderer(this);
|
||
|
}
|
||
|
// ------ Function for swapWhileDragging option
|
||
|
// identical to checkCollision() except that here we add boundaries.
|
||
|
static checkCollisionTwoItemsForSwaping(item, item2) {
|
||
|
// if the cols or rows of the items are 1 , doesnt make any sense to set a boundary. Only if the item is bigger we set a boundary
|
||
|
const horizontalBoundaryItem1 = item.cols === 1 ? 0 : 1;
|
||
|
const horizontalBoundaryItem2 = item2.cols === 1 ? 0 : 1;
|
||
|
const verticalBoundaryItem1 = item.rows === 1 ? 0 : 1;
|
||
|
const verticalBoundaryItem2 = item2.rows === 1 ? 0 : 1;
|
||
|
return (item.x + horizontalBoundaryItem1 < item2.x + item2.cols &&
|
||
|
item.x + item.cols > item2.x + horizontalBoundaryItem2 &&
|
||
|
item.y + verticalBoundaryItem1 < item2.y + item2.rows &&
|
||
|
item.y + item.rows > item2.y + verticalBoundaryItem2);
|
||
|
}
|
||
|
checkCollisionTwoItems(item, item2) {
|
||
|
const collision = item.x < item2.x + item2.cols &&
|
||
|
item.x + item.cols > item2.x &&
|
||
|
item.y < item2.y + item2.rows &&
|
||
|
item.y + item.rows > item2.y;
|
||
|
if (!collision) {
|
||
|
return false;
|
||
|
}
|
||
|
if (!this.$options.allowMultiLayer) {
|
||
|
return true;
|
||
|
}
|
||
|
const defaultLayerIndex = this.$options.defaultLayerIndex;
|
||
|
const layerIndex = item.layerIndex === undefined ? defaultLayerIndex : item.layerIndex;
|
||
|
const layerIndex2 = item2.layerIndex === undefined ? defaultLayerIndex : item2.layerIndex;
|
||
|
return layerIndex === layerIndex2;
|
||
|
}
|
||
|
ngOnInit() {
|
||
|
if (this.options.initCallback) {
|
||
|
this.options.initCallback(this);
|
||
|
}
|
||
|
this.calculateLayout$
|
||
|
.pipe(debounceTime(0), takeUntil(this.destroy$))
|
||
|
.subscribe(() => this.calculateLayout());
|
||
|
this.resize$
|
||
|
.pipe(
|
||
|
// Cancel previously scheduled DOM timer if `calculateLayout()` has been called
|
||
|
// within this time range.
|
||
|
switchMap(() => timer(100)), takeUntil(this.destroy$))
|
||
|
.subscribe(() => this.resize());
|
||
|
}
|
||
|
ngOnChanges(changes) {
|
||
|
if (changes.options) {
|
||
|
this.setOptions();
|
||
|
this.options.api = {
|
||
|
optionsChanged: this.optionsChanged,
|
||
|
resize: this.onResize,
|
||
|
getNextPossiblePosition: this.getNextPossiblePosition,
|
||
|
getFirstPossiblePosition: this.getFirstPossiblePosition,
|
||
|
getLastPossiblePosition: this.getLastPossiblePosition,
|
||
|
getItemComponent: (item) => this.getItemComponent(item)
|
||
|
};
|
||
|
this.columns = this.$options.minCols;
|
||
|
this.rows = this.$options.minRows + this.$options.addEmptyRowsCount;
|
||
|
this.setGridSize();
|
||
|
this.calculateLayout();
|
||
|
}
|
||
|
}
|
||
|
resize() {
|
||
|
let height;
|
||
|
let width;
|
||
|
if (this.$options.gridType === 'fit' && !this.mobile) {
|
||
|
width = this.el.offsetWidth;
|
||
|
height = this.el.offsetHeight;
|
||
|
}
|
||
|
else {
|
||
|
width = this.el.clientWidth;
|
||
|
height = this.el.clientHeight;
|
||
|
}
|
||
|
if ((width !== this.curWidth || height !== this.curHeight) &&
|
||
|
this.checkIfToResize()) {
|
||
|
this.onResize();
|
||
|
}
|
||
|
}
|
||
|
setOptions() {
|
||
|
this.$options = GridsterUtils.merge(this.$options, this.options, this.$options);
|
||
|
if (!this.$options.disableWindowResize && !this.windowResize) {
|
||
|
this.windowResize = this.renderer.listen('window', 'resize', this.onResize);
|
||
|
}
|
||
|
else if (this.$options.disableWindowResize && this.windowResize) {
|
||
|
this.windowResize();
|
||
|
this.windowResize = null;
|
||
|
}
|
||
|
this.emptyCell.updateOptions();
|
||
|
}
|
||
|
ngOnDestroy() {
|
||
|
this.destroy$.next();
|
||
|
this.previewStyle$.complete();
|
||
|
if (this.windowResize) {
|
||
|
this.windowResize();
|
||
|
}
|
||
|
if (this.options && this.options.destroyCallback) {
|
||
|
this.options.destroyCallback(this);
|
||
|
}
|
||
|
if (this.options && this.options.api) {
|
||
|
this.options.api.resize = undefined;
|
||
|
this.options.api.optionsChanged = undefined;
|
||
|
this.options.api.getNextPossiblePosition = undefined;
|
||
|
this.options.api = undefined;
|
||
|
}
|
||
|
this.emptyCell.destroy();
|
||
|
this.emptyCell = null;
|
||
|
this.compact.destroy();
|
||
|
this.compact = null;
|
||
|
}
|
||
|
checkIfToResize() {
|
||
|
const clientWidth = this.el.clientWidth;
|
||
|
const offsetWidth = this.el.offsetWidth;
|
||
|
const scrollWidth = this.el.scrollWidth;
|
||
|
const clientHeight = this.el.clientHeight;
|
||
|
const offsetHeight = this.el.offsetHeight;
|
||
|
const scrollHeight = this.el.scrollHeight;
|
||
|
const verticalScrollPresent = clientWidth < offsetWidth &&
|
||
|
scrollHeight > offsetHeight &&
|
||
|
scrollHeight - offsetHeight < offsetWidth - clientWidth;
|
||
|
const horizontalScrollPresent = clientHeight < offsetHeight &&
|
||
|
scrollWidth > offsetWidth &&
|
||
|
scrollWidth - offsetWidth < offsetHeight - clientHeight;
|
||
|
if (verticalScrollPresent) {
|
||
|
return false;
|
||
|
}
|
||
|
return !horizontalScrollPresent;
|
||
|
}
|
||
|
checkIfMobile() {
|
||
|
if (this.$options.useBodyForBreakpoint) {
|
||
|
return this.$options.mobileBreakpoint > document.body.clientWidth;
|
||
|
}
|
||
|
else {
|
||
|
return this.$options.mobileBreakpoint > this.curWidth;
|
||
|
}
|
||
|
}
|
||
|
setGridSize() {
|
||
|
const el = this.el;
|
||
|
let width;
|
||
|
let height;
|
||
|
if (this.$options.setGridSize ||
|
||
|
(this.$options.gridType === GridType.Fit && !this.mobile)) {
|
||
|
width = el.offsetWidth;
|
||
|
height = el.offsetHeight;
|
||
|
}
|
||
|
else {
|
||
|
width = el.clientWidth;
|
||
|
height = el.clientHeight;
|
||
|
}
|
||
|
this.curWidth = width;
|
||
|
this.curHeight = height;
|
||
|
}
|
||
|
setGridDimensions() {
|
||
|
this.setGridSize();
|
||
|
if (!this.mobile && this.checkIfMobile()) {
|
||
|
this.mobile = !this.mobile;
|
||
|
this.renderer.addClass(this.el, 'mobile');
|
||
|
}
|
||
|
else if (this.mobile && !this.checkIfMobile()) {
|
||
|
this.mobile = !this.mobile;
|
||
|
this.renderer.removeClass(this.el, 'mobile');
|
||
|
}
|
||
|
let rows = this.$options.minRows;
|
||
|
let columns = this.$options.minCols;
|
||
|
let widgetsIndex = this.grid.length - 1;
|
||
|
let widget;
|
||
|
for (; widgetsIndex >= 0; widgetsIndex--) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
if (!widget.notPlaced) {
|
||
|
rows = Math.max(rows, widget.$item.y + widget.$item.rows);
|
||
|
columns = Math.max(columns, widget.$item.x + widget.$item.cols);
|
||
|
}
|
||
|
}
|
||
|
rows += this.$options.addEmptyRowsCount;
|
||
|
if (this.columns !== columns || this.rows !== rows) {
|
||
|
this.columns = columns;
|
||
|
this.rows = rows;
|
||
|
if (this.options.gridSizeChangedCallback) {
|
||
|
this.options.gridSizeChangedCallback(this);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
calculateLayout() {
|
||
|
if (this.compact) {
|
||
|
this.compact.checkCompact();
|
||
|
}
|
||
|
this.setGridDimensions();
|
||
|
if (this.$options.outerMargin) {
|
||
|
let marginWidth = -this.$options.margin;
|
||
|
if (this.$options.outerMarginLeft !== null) {
|
||
|
marginWidth += this.$options.outerMarginLeft;
|
||
|
this.renderer.setStyle(this.el, 'padding-left', this.$options.outerMarginLeft + 'px');
|
||
|
}
|
||
|
else {
|
||
|
marginWidth += this.$options.margin;
|
||
|
this.renderer.setStyle(this.el, 'padding-left', this.$options.margin + 'px');
|
||
|
}
|
||
|
if (this.$options.outerMarginRight !== null) {
|
||
|
marginWidth += this.$options.outerMarginRight;
|
||
|
this.renderer.setStyle(this.el, 'padding-right', this.$options.outerMarginRight + 'px');
|
||
|
}
|
||
|
else {
|
||
|
marginWidth += this.$options.margin;
|
||
|
this.renderer.setStyle(this.el, 'padding-right', this.$options.margin + 'px');
|
||
|
}
|
||
|
this.curColWidth = (this.curWidth - marginWidth) / this.columns;
|
||
|
let marginHeight = -this.$options.margin;
|
||
|
if (this.$options.outerMarginTop !== null) {
|
||
|
marginHeight += this.$options.outerMarginTop;
|
||
|
this.renderer.setStyle(this.el, 'padding-top', this.$options.outerMarginTop + 'px');
|
||
|
}
|
||
|
else {
|
||
|
marginHeight += this.$options.margin;
|
||
|
this.renderer.setStyle(this.el, 'padding-top', this.$options.margin + 'px');
|
||
|
}
|
||
|
if (this.$options.outerMarginBottom !== null) {
|
||
|
marginHeight += this.$options.outerMarginBottom;
|
||
|
this.renderer.setStyle(this.el, 'padding-bottom', this.$options.outerMarginBottom + 'px');
|
||
|
}
|
||
|
else {
|
||
|
marginHeight += this.$options.margin;
|
||
|
this.renderer.setStyle(this.el, 'padding-bottom', this.$options.margin + 'px');
|
||
|
}
|
||
|
this.curRowHeight =
|
||
|
((this.curHeight - marginHeight) / this.rows) *
|
||
|
this.$options.rowHeightRatio;
|
||
|
}
|
||
|
else {
|
||
|
this.curColWidth = (this.curWidth + this.$options.margin) / this.columns;
|
||
|
this.curRowHeight =
|
||
|
((this.curHeight + this.$options.margin) / this.rows) *
|
||
|
this.$options.rowHeightRatio;
|
||
|
this.renderer.setStyle(this.el, 'padding-left', 0 + 'px');
|
||
|
this.renderer.setStyle(this.el, 'padding-right', 0 + 'px');
|
||
|
this.renderer.setStyle(this.el, 'padding-top', 0 + 'px');
|
||
|
this.renderer.setStyle(this.el, 'padding-bottom', 0 + 'px');
|
||
|
}
|
||
|
this.gridRenderer.updateGridster();
|
||
|
if (this.$options.setGridSize) {
|
||
|
this.renderer.addClass(this.el, 'gridSize');
|
||
|
if (!this.mobile) {
|
||
|
this.renderer.setStyle(this.el, 'width', this.columns * this.curColWidth + this.$options.margin + 'px');
|
||
|
this.renderer.setStyle(this.el, 'height', this.rows * this.curRowHeight + this.$options.margin + 'px');
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
this.renderer.removeClass(this.el, 'gridSize');
|
||
|
this.renderer.setStyle(this.el, 'width', '');
|
||
|
this.renderer.setStyle(this.el, 'height', '');
|
||
|
}
|
||
|
this.updateGrid();
|
||
|
let widgetsIndex = this.grid.length - 1;
|
||
|
let widget;
|
||
|
for (; widgetsIndex >= 0; widgetsIndex--) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
widget.setSize();
|
||
|
widget.drag.toggle();
|
||
|
widget.resize.toggle();
|
||
|
}
|
||
|
this.resize$.next();
|
||
|
}
|
||
|
updateGrid() {
|
||
|
if (this.$options.displayGrid === 'always' && !this.mobile) {
|
||
|
this.renderer.addClass(this.el, 'display-grid');
|
||
|
}
|
||
|
else if (this.$options.displayGrid === 'onDrag&Resize' &&
|
||
|
this.dragInProgress) {
|
||
|
this.renderer.addClass(this.el, 'display-grid');
|
||
|
}
|
||
|
else if (this.$options.displayGrid === 'none' ||
|
||
|
!this.dragInProgress ||
|
||
|
this.mobile) {
|
||
|
this.renderer.removeClass(this.el, 'display-grid');
|
||
|
}
|
||
|
this.setGridDimensions();
|
||
|
this.gridColumns.length = GridsterComponent.getNewArrayLength(this.columns, this.curWidth, this.curColWidth);
|
||
|
this.gridRows.length = GridsterComponent.getNewArrayLength(this.rows, this.curHeight, this.curRowHeight);
|
||
|
this.cdRef.markForCheck();
|
||
|
}
|
||
|
addItem(itemComponent) {
|
||
|
if (itemComponent.$item.cols === undefined) {
|
||
|
itemComponent.$item.cols = this.$options.defaultItemCols;
|
||
|
itemComponent.item.cols = itemComponent.$item.cols;
|
||
|
itemComponent.itemChanged();
|
||
|
}
|
||
|
if (itemComponent.$item.rows === undefined) {
|
||
|
itemComponent.$item.rows = this.$options.defaultItemRows;
|
||
|
itemComponent.item.rows = itemComponent.$item.rows;
|
||
|
itemComponent.itemChanged();
|
||
|
}
|
||
|
if (itemComponent.$item.x === -1 || itemComponent.$item.y === -1) {
|
||
|
this.autoPositionItem(itemComponent);
|
||
|
}
|
||
|
else if (this.checkCollision(itemComponent.$item)) {
|
||
|
if (!this.$options.disableWarnings) {
|
||
|
itemComponent.notPlaced = true;
|
||
|
console.warn("Can't be placed in the bounds of the dashboard, trying to auto position!/n" +
|
||
|
JSON.stringify(itemComponent.item, ['cols', 'rows', 'x', 'y']));
|
||
|
}
|
||
|
if (!this.$options.disableAutoPositionOnConflict) {
|
||
|
this.autoPositionItem(itemComponent);
|
||
|
}
|
||
|
else {
|
||
|
itemComponent.notPlaced = true;
|
||
|
}
|
||
|
}
|
||
|
this.grid.push(itemComponent);
|
||
|
this.calculateLayout$.next();
|
||
|
}
|
||
|
removeItem(itemComponent) {
|
||
|
this.grid.splice(this.grid.indexOf(itemComponent), 1);
|
||
|
this.calculateLayout$.next();
|
||
|
if (this.options.itemRemovedCallback) {
|
||
|
this.options.itemRemovedCallback(itemComponent.item, itemComponent);
|
||
|
}
|
||
|
}
|
||
|
checkCollision(item) {
|
||
|
let collision = false;
|
||
|
if (this.options.itemValidateCallback) {
|
||
|
collision = !this.options.itemValidateCallback(item);
|
||
|
}
|
||
|
if (!collision && this.checkGridCollision(item)) {
|
||
|
collision = true;
|
||
|
}
|
||
|
if (!collision) {
|
||
|
const c = this.findItemWithItem(item);
|
||
|
if (c) {
|
||
|
collision = c;
|
||
|
}
|
||
|
}
|
||
|
return collision;
|
||
|
}
|
||
|
checkGridCollision(item) {
|
||
|
const noNegativePosition = item.y > -1 && item.x > -1;
|
||
|
const maxGridCols = item.cols + item.x <= this.$options.maxCols;
|
||
|
const maxGridRows = item.rows + item.y <= this.$options.maxRows;
|
||
|
const maxItemCols = item.maxItemCols === undefined
|
||
|
? this.$options.maxItemCols
|
||
|
: item.maxItemCols;
|
||
|
const minItemCols = item.minItemCols === undefined
|
||
|
? this.$options.minItemCols
|
||
|
: item.minItemCols;
|
||
|
const maxItemRows = item.maxItemRows === undefined
|
||
|
? this.$options.maxItemRows
|
||
|
: item.maxItemRows;
|
||
|
const minItemRows = item.minItemRows === undefined
|
||
|
? this.$options.minItemRows
|
||
|
: item.minItemRows;
|
||
|
const inColsLimits = item.cols <= maxItemCols && item.cols >= minItemCols;
|
||
|
const inRowsLimits = item.rows <= maxItemRows && item.rows >= minItemRows;
|
||
|
const minAreaLimit = item.minItemArea === undefined
|
||
|
? this.$options.minItemArea
|
||
|
: item.minItemArea;
|
||
|
const maxAreaLimit = item.maxItemArea === undefined
|
||
|
? this.$options.maxItemArea
|
||
|
: item.maxItemArea;
|
||
|
const area = item.cols * item.rows;
|
||
|
const inMinArea = minAreaLimit <= area;
|
||
|
const inMaxArea = maxAreaLimit >= area;
|
||
|
return !(noNegativePosition &&
|
||
|
maxGridCols &&
|
||
|
maxGridRows &&
|
||
|
inColsLimits &&
|
||
|
inRowsLimits &&
|
||
|
inMinArea &&
|
||
|
inMaxArea);
|
||
|
}
|
||
|
findItemWithItem(item) {
|
||
|
let widgetsIndex = 0;
|
||
|
let widget;
|
||
|
for (; widgetsIndex < this.grid.length; widgetsIndex++) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
if (widget.$item !== item &&
|
||
|
this.checkCollisionTwoItems(widget.$item, item)) {
|
||
|
return widget;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
findItemsWithItem(item) {
|
||
|
const a = [];
|
||
|
let widgetsIndex = 0;
|
||
|
let widget;
|
||
|
for (; widgetsIndex < this.grid.length; widgetsIndex++) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
if (widget.$item !== item &&
|
||
|
this.checkCollisionTwoItems(widget.$item, item)) {
|
||
|
a.push(widget);
|
||
|
}
|
||
|
}
|
||
|
return a;
|
||
|
}
|
||
|
autoPositionItem(itemComponent) {
|
||
|
if (this.getNextPossiblePosition(itemComponent.$item)) {
|
||
|
itemComponent.notPlaced = false;
|
||
|
itemComponent.item.x = itemComponent.$item.x;
|
||
|
itemComponent.item.y = itemComponent.$item.y;
|
||
|
itemComponent.itemChanged();
|
||
|
}
|
||
|
else {
|
||
|
itemComponent.notPlaced = true;
|
||
|
if (!this.$options.disableWarnings) {
|
||
|
console.warn("Can't be placed in the bounds of the dashboard!/n" +
|
||
|
JSON.stringify(itemComponent.item, ['cols', 'rows', 'x', 'y']));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
pixelsToPositionX(x, roundingMethod, noLimit) {
|
||
|
const position = roundingMethod(x / this.curColWidth);
|
||
|
if (noLimit) {
|
||
|
return position;
|
||
|
}
|
||
|
else {
|
||
|
return Math.max(position, 0);
|
||
|
}
|
||
|
}
|
||
|
pixelsToPositionY(y, roundingMethod, noLimit) {
|
||
|
const position = roundingMethod(y / this.curRowHeight);
|
||
|
if (noLimit) {
|
||
|
return position;
|
||
|
}
|
||
|
else {
|
||
|
return Math.max(position, 0);
|
||
|
}
|
||
|
}
|
||
|
positionXToPixels(x) {
|
||
|
return x * this.curColWidth;
|
||
|
}
|
||
|
positionYToPixels(y) {
|
||
|
return y * this.curRowHeight;
|
||
|
}
|
||
|
getItemComponent(item) {
|
||
|
return this.grid.find(c => c.item === item);
|
||
|
}
|
||
|
// ------ Functions for swapWhileDragging option
|
||
|
// identical to checkCollision() except that this function calls findItemWithItemForSwaping() instead of findItemWithItem()
|
||
|
checkCollisionForSwaping(item) {
|
||
|
let collision = false;
|
||
|
if (this.options.itemValidateCallback) {
|
||
|
collision = !this.options.itemValidateCallback(item);
|
||
|
}
|
||
|
if (!collision && this.checkGridCollision(item)) {
|
||
|
collision = true;
|
||
|
}
|
||
|
if (!collision) {
|
||
|
const c = this.findItemWithItemForSwapping(item);
|
||
|
if (c) {
|
||
|
collision = c;
|
||
|
}
|
||
|
}
|
||
|
return collision;
|
||
|
}
|
||
|
// identical to findItemWithItem() except that this function calls checkCollisionTwoItemsForSwaping() instead of checkCollisionTwoItems()
|
||
|
findItemWithItemForSwapping(item) {
|
||
|
let widgetsIndex = this.grid.length - 1;
|
||
|
let widget;
|
||
|
for (; widgetsIndex > -1; widgetsIndex--) {
|
||
|
widget = this.grid[widgetsIndex];
|
||
|
if (widget.$item !== item &&
|
||
|
GridsterComponent.checkCollisionTwoItemsForSwaping(widget.$item, item)) {
|
||
|
return widget;
|
||
|
}
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
previewStyle(drag = false) {
|
||
|
if (this.movingItem) {
|
||
|
if (this.compact && drag) {
|
||
|
this.compact.checkCompactItem(this.movingItem);
|
||
|
}
|
||
|
this.previewStyle$.next(this.movingItem);
|
||
|
}
|
||
|
else {
|
||
|
this.previewStyle$.next(null);
|
||
|
}
|
||
|
}
|
||
|
// ------ End of functions for swapWhileDragging option
|
||
|
// eslint-disable-next-line @typescript-eslint/member-ordering
|
||
|
static getNewArrayLength(length, overallSize, size) {
|
||
|
const newLength = Math.max(length, Math.floor(overallSize / size));
|
||
|
if (newLength < 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
if (Number.isFinite(newLength)) {
|
||
|
return Math.floor(newLength);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: GridsterComponent, deps: [{ token: ElementRef }, { token: Renderer2 }, { token: ChangeDetectorRef }, { token: NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
|
||
|
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: GridsterComponent, isStandalone: true, selector: "gridster", inputs: { options: "options" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"gridster-column\"\n *ngFor=\"let column of gridColumns; let i = index;\"\n [ngStyle]=\"gridRenderer.getGridColumnStyle(i)\"\n></div>\n<div\n class=\"gridster-row\"\n *ngFor=\"let row of gridRows; let i = index;\"\n [ngStyle]=\"gridRenderer.getGridRowStyle(i)\"\n></div>\n<ng-content></ng-content>\n<gridster-preview\n [gridRenderer]=\"gridRenderer\"\n [previewStyle$]=\"previewStyle$\"\n class=\"gridster-preview\"\n></gridster-preview>\n", styles: ["gridster{position:relative;box-sizing:border-box;background:grey;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:block}gridster.fit{overflow-x:hidden;overflow-y:hidden}gridster.scrollVertical{overflow-x:hidden;overflow-y:auto}gridster.scrollHorizontal{overflow-x:auto;overflow-y:hidden}gridster.fixed{overflow:auto}gridster.mobile{overflow-x:hidden;overflow-y:auto}gridster.mobile gridster-item{position:relative}gridster.gridSize{height:initial;width:initial}gridster.gridSize.fit{height:100%;width:100%}gridster .gridster-column,gridster .gridster-row{position:absolute;display:none;transition:.3s;box-sizing:border-box}gridster.display-grid .gridster-column,gridster.display-grid .gridster-row{display:block}gridster .gridster-column{border-left:1px solid white;border-right:1px solid white}gridster .gridster-row{border-top:1px solid white;border-bottom:1px solid white}\n"], dependencies: [{ kind: "directive", type: NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: GridsterPreviewComponent, selector: "gridster-preview", inputs: ["previewStyle$", "gridRenderer"] }], encapsulation: i0.ViewEncapsulation.None }); }
|
||
|
}
|
||
|
export { GridsterComponent };
|
||
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: GridsterComponent, decorators: [{
|
||
|
type: Component,
|
||
|
args: [{ selector: 'gridster', encapsulation: ViewEncapsulation.None, standalone: true, imports: [NgForOf, NgStyle, GridsterPreviewComponent], template: "<div\n class=\"gridster-column\"\n *ngFor=\"let column of gridColumns; let i = index;\"\n [ngStyle]=\"gridRenderer.getGridColumnStyle(i)\"\n></div>\n<div\n class=\"gridster-row\"\n *ngFor=\"let row of gridRows; let i = index;\"\n [ngStyle]=\"gridRenderer.getGridRowStyle(i)\"\n></div>\n<ng-content></ng-content>\n<gridster-preview\n [gridRenderer]=\"gridRenderer\"\n [previewStyle$]=\"previewStyle$\"\n class=\"gridster-preview\"\n></gridster-preview>\n", styles: ["gridster{position:relative;box-sizing:border-box;background:grey;width:100%;height:100%;-webkit-user-select:none;user-select:none;display:block}gridster.fit{overflow-x:hidden;overflow-y:hidden}gridster.scrollVertical{overflow-x:hidden;overflow-y:auto}gridster.scrollHorizontal{overflow-x:auto;overflow-y:hidden}gridster.fixed{overflow:auto}gridster.mobile{overflow-x:hidden;overflow-y:auto}gridster.mobile gridster-item{position:relative}gridster.gridSize{height:initial;width:initial}gridster.gridSize.fit{height:100%;width:100%}gridster .gridster-column,gridster .gridster-row{position:absolute;display:none;transition:.3s;box-sizing:border-box}gridster.display-grid .gridster-column,gridster.display-grid .gridster-row{display:block}gridster .gridster-column{border-left:1px solid white;border-right:1px solid white}gridster .gridster-row{border-top:1px solid white;border-bottom:1px solid white}\n"] }]
|
||
|
}], ctorParameters: function () { return [{ type: i0.ElementRef, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [ElementRef]
|
||
|
}] }, { type: i0.Renderer2, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [Renderer2]
|
||
|
}] }, { type: i0.ChangeDetectorRef, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [ChangeDetectorRef]
|
||
|
}] }, { type: i0.NgZone, decorators: [{
|
||
|
type: Inject,
|
||
|
args: [NgZone]
|
||
|
}] }]; }, propDecorators: { options: [{
|
||
|
type: Input
|
||
|
}] } });
|
||
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZHN0ZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1ncmlkc3RlcjIvc3JjL2xpYi9ncmlkc3Rlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWdyaWRzdGVyMi9zcmMvbGliL2dyaWRzdGVyLmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNuRCxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUlOLFNBQVMsRUFFVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTVELE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2xFLE9BQU8sRUFBa0IsUUFBUSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFdEUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFLaEUsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHlCQUF5QixDQUFDOztBQUV4RCxNQVNhLGlCQUFpQjtJQThCNUIsWUFDc0IsRUFBYyxFQUNSLFFBQW1CLEVBQ1gsS0FBd0IsRUFDbkMsSUFBWTtRQUZULGFBQVEsR0FBUixRQUFRLENBQVc7UUFDWCxV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
|