a somewhat working example of a dashboard
This commit is contained in:
@@ -1,58 +1,110 @@
|
|||||||
<style>
|
<style>
|
||||||
.grid-container {
|
.example-list {
|
||||||
margin: 10px;
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-card {
|
.example-list li {
|
||||||
position: absolute;
|
display: table-cell;
|
||||||
top: 0px;
|
padding: 4px;
|
||||||
left: 0px;
|
|
||||||
right: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.more-button {
|
.example-container {
|
||||||
float: right;
|
display: flex;
|
||||||
font-size: 2em;
|
flex-wrap: wrap;
|
||||||
|
min-width: 600px;
|
||||||
|
max-width: 1200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-card-content {
|
.example-box {
|
||||||
|
width: var(--box-width);
|
||||||
|
height: var(--box-height);
|
||||||
|
border: solid 1px #ccc;
|
||||||
|
font-size: 30pt;
|
||||||
|
font-weight: bold;
|
||||||
|
color: rgba(0, 0, 0, 0.87);
|
||||||
|
cursor: grab;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
transition: box-shadow 200ms cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14),
|
||||||
|
0 1px 5px 0 rgba(0, 0, 0, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-box--wide {
|
||||||
|
width: 400px;
|
||||||
|
height: var(--box-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-box:active {
|
||||||
|
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
|
0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cdk-drop-list {
|
.cdk-drop-list {
|
||||||
height: 100%;
|
display: flex;
|
||||||
width: 100%;
|
padding-right: 10px;
|
||||||
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.cdk-drag-preview {
|
.cdk-drag-preview {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
opacity: 0.5;
|
border-radius: 4px;
|
||||||
}
|
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
|
||||||
|
0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
|
||||||
.cdk-drag-animating {
|
|
||||||
transition: unset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cdk-drag-placeholder {
|
.cdk-drag-placeholder {
|
||||||
display: none;
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cdk-drag-animating {
|
||||||
|
transition: transform 250ms cubic-bezier(0, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cdk-drop-list-dragging {
|
||||||
|
cursor: grabbing !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
<div class="grid-container" style="height: 615px; overflow: hidden;">
|
<h1>Drag&Drop with a flex-wrap</h1>
|
||||||
<mat-grid-list cols="8" rowHeight="1:1" gutterSize="15px">
|
|
||||||
<mat-grid-tile *ngFor="let card of cards; let i = index;"
|
<button (click)="add()">Add</button>
|
||||||
[colspan]="card.cols" [rowspan]="card.rows">
|
<button (click)="shuffle()">Shuffle</button>
|
||||||
<cdk-drop-list [cdkDropListConnectedTo]="drops" [cdkDropListData]="i" >
|
|
||||||
<mat-card cdkDrag (cdkDragEntered)="entered($event)" [cdkDragData]="i"
|
<br />
|
||||||
class="dashboard-card" [style.backgroundColor]="card.color">
|
|
||||||
<mat-icon cdkDragHandle class="more-button">drag_handle</mat-icon>
|
<ul class="example-list">
|
||||||
<mat-card-content class="dashboard-card-content">
|
<li *ngFor="let item of items">{{ item }}</li>
|
||||||
<h1>{{card.title}}</h1>
|
</ul>
|
||||||
</mat-card-content>
|
|
||||||
</mat-card>
|
<div
|
||||||
</cdk-drop-list>
|
class="example-container"
|
||||||
</mat-grid-tile>
|
cdkDropListGroup
|
||||||
</mat-grid-list>
|
[ngStyle]="{ '--box-width': boxWidth, '--box-height': boxHeight }"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
cdkDropList
|
||||||
|
(cdkDropListEntered)="onDropListEntered($event)"
|
||||||
|
(cdkDropListDropped)="onDropListDropped()"
|
||||||
|
></div>
|
||||||
|
<div
|
||||||
|
cdkDropList
|
||||||
|
(cdkDropListEntered)="onDropListEntered($event)"
|
||||||
|
(cdkDropListDropped)="onDropListDropped()"
|
||||||
|
*ngFor="let item of items"
|
||||||
|
>
|
||||||
|
<div cdkDrag class="example-box" [ngClass]="{'example-box--wide': item%2==1}">{{ item }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1,111 +1,119 @@
|
|||||||
import { Component, QueryList, ViewChildren } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
import {CdkDragDrop, CdkDragEnter, CdkDropList, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
|
import { CdkDragEnter, CdkDropList, moveItemInArray, DragRef} from '@angular/cdk/drag-drop';
|
||||||
|
import { AfterViewInit } from '@angular/core';
|
||||||
|
import { ViewChild } from '@angular/core';
|
||||||
|
|
||||||
const COLORS = [
|
|
||||||
'#ea4335',
|
|
||||||
'#4285f4',
|
|
||||||
'#fbbc04',
|
|
||||||
'#34a853',
|
|
||||||
'#fa7b17',
|
|
||||||
'#f538a0',
|
|
||||||
'#a142f4',
|
|
||||||
'#24c1e0',
|
|
||||||
'#9aa0a6',
|
|
||||||
'#5195ea',
|
|
||||||
'#e25142',
|
|
||||||
'#f5c518',
|
|
||||||
'#41af6a',
|
|
||||||
'#f6aea9',
|
|
||||||
'#a50e0e',
|
|
||||||
'#aecbfa',
|
|
||||||
'#174ea6',
|
|
||||||
'#fde293',
|
|
||||||
'#a8dab5',
|
|
||||||
'#0d652d',
|
|
||||||
'#fdc69c',
|
|
||||||
'#fba9d6',
|
|
||||||
'#c92786',
|
|
||||||
'#d7aefb',
|
|
||||||
'#8430ce',
|
|
||||||
'#a1e4f2',
|
|
||||||
'#007b83',
|
|
||||||
'#e8eaed',
|
|
||||||
'#b9d4f6',
|
|
||||||
'#f3b9b3',
|
|
||||||
'#fbe7a2',
|
|
||||||
'#b3dfc3',
|
|
||||||
]
|
|
||||||
|
|
||||||
function getColor() {
|
|
||||||
return COLORS[Math.floor(Math.random() * 32)];
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-customizable-grid',
|
selector: 'app-customizable-grid',
|
||||||
templateUrl: './customizable-grid.component.html'
|
templateUrl: './customizable-grid.component.html'
|
||||||
})
|
})
|
||||||
export class CustomizableGridComponent {
|
export class CustomizableGridComponent implements AfterViewInit {
|
||||||
entered($event: CdkDragEnter) {
|
@ViewChild(CdkDropList) placeholder!: CdkDropList;
|
||||||
console.log($event.item.data, $event.container.data);
|
|
||||||
moveItemInArray(this.cards, $event.item.data, $event.container.data);
|
|
||||||
}
|
|
||||||
entered2($event: CdkDragEnter) {
|
|
||||||
console.log($event.item.data, $event.container.data);
|
|
||||||
moveItemInArray(this.cards, $event.item.data, $event.container.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
drop(event: CdkDragDrop<any[]>) {
|
private target: CdkDropList|null = null;
|
||||||
|
private targetIndex: number = 0;
|
||||||
|
private source: CdkDropList|null = null;
|
||||||
|
private sourceIndex: number = 0;
|
||||||
|
private dragRef: DragRef|null = null;
|
||||||
|
|
||||||
}
|
items: Array<number> = [1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
|
||||||
done(){
|
boxWidth = '200px';
|
||||||
|
boxHeight = '200px';
|
||||||
}
|
|
||||||
|
|
||||||
@ViewChildren(CdkDropList) dropsQuery!: QueryList<CdkDropList>;
|
|
||||||
|
|
||||||
drops!: CdkDropList[];
|
|
||||||
|
|
||||||
ngAfterViewInit() {
|
ngAfterViewInit() {
|
||||||
this.dropsQuery.changes.subscribe(() => {
|
const placeholderElement = this.placeholder.element.nativeElement;
|
||||||
this.drops = this.dropsQuery.toArray()
|
|
||||||
})
|
placeholderElement.style.display = 'none';
|
||||||
Promise.resolve().then(() => {
|
placeholderElement.parentNode!.removeChild(placeholderElement);
|
||||||
this.drops = this.dropsQuery.toArray();
|
|
||||||
console.log(this.drops);
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Based on the screen size, switch from standard to one column per row */
|
add() {
|
||||||
cards = [
|
this.items.push(this.items.length + 1);
|
||||||
{ title: 'Card 1', cols: 2, rows: 2, color: getColor()},
|
}
|
||||||
{ title: 'Card 2', cols: 1, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 3', cols: 3, rows: 1, color: getColor() },
|
shuffle() {
|
||||||
{ title: 'Card 4', cols: 1, rows: 1, color: getColor() },
|
this.items.sort(function () {
|
||||||
{ title: 'Card 5', cols: 1, rows: 1, color: getColor() },
|
return 0.5 - Math.random();
|
||||||
{ title: 'Card 6', cols: 1, rows: 1, color: getColor() },
|
});
|
||||||
{ title: 'Card 7', cols: 1, rows: 1, color: getColor() },
|
}
|
||||||
{ title: 'Card 8', cols: 1, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 9', cols: 1, rows: 3, color: getColor() },
|
onDropListDropped() {
|
||||||
{ title: 'Card 10', cols: 1, rows: 1, color: getColor() },
|
if (!this.target) {
|
||||||
{ title: 'Card 11', cols: 1, rows: 1, color: getColor() },
|
return;
|
||||||
{ title: 'Card 12', cols: 2, rows: 1, color: getColor() },
|
}
|
||||||
{ title: 'Card 13', cols: 1, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 14', cols: 1, rows: 1, color: getColor() },
|
const placeholderElement: HTMLElement =
|
||||||
{ title: 'Card 15', cols: 1, rows: 2, color: getColor() },
|
this.placeholder.element.nativeElement;
|
||||||
{ title: 'Card 16', cols: 2, rows: 1, color: getColor() },
|
const placeholderParentElement: HTMLElement =
|
||||||
{ title: 'Card 17', cols: 1, rows: 1, color: getColor() },
|
placeholderElement.parentElement!;
|
||||||
{ title: 'Card 18', cols: 2, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 19', cols: 1, rows: 1, color: getColor() },
|
placeholderElement.style.display = 'none';
|
||||||
{ title: 'Card 20', cols: 1, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 21', cols: 1, rows: 1, color: getColor()},
|
placeholderParentElement.removeChild(placeholderElement);
|
||||||
/* { title: 'Card 22', cols: 1, rows: 1, color: getColor() },
|
placeholderParentElement.appendChild(placeholderElement);
|
||||||
{ title: 'Card 23', cols: 1, rows: 1, color: getColor() },
|
placeholderParentElement.insertBefore(
|
||||||
{ title: 'Card 24', cols: 1, rows: 1, color: getColor() },
|
this.source!.element.nativeElement,
|
||||||
{ title: 'Card 25', cols: 1, rows: 1, color: getColor() },
|
placeholderParentElement.children[this.sourceIndex]
|
||||||
{ title: 'Card 26', cols: 1, rows: 1, color: getColor() },
|
);
|
||||||
{ title: 'Card 27', cols: 1, rows: 1, color: getColor() },
|
|
||||||
{ title: 'Card 28', cols: 1, rows: 1, color: getColor() },
|
if (this.placeholder._dropListRef.isDragging() && this.dragRef != null) {
|
||||||
{ title: 'Card 29', cols: 1, rows: 1, color: getColor() } */
|
this.placeholder._dropListRef.exit(this.dragRef);
|
||||||
];
|
}
|
||||||
|
|
||||||
|
this.target = null;
|
||||||
|
this.source = null;
|
||||||
|
this.dragRef = null;
|
||||||
|
|
||||||
|
if (this.sourceIndex !== this.targetIndex) {
|
||||||
|
moveItemInArray(this.items, this.sourceIndex, this.targetIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDropListEntered({ item, container }: CdkDragEnter) {
|
||||||
|
if (container == this.placeholder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeholderElement: HTMLElement =
|
||||||
|
this.placeholder.element.nativeElement;
|
||||||
|
const sourceElement: HTMLElement = item.dropContainer.element.nativeElement;
|
||||||
|
const dropElement: HTMLElement = container.element.nativeElement;
|
||||||
|
const dragIndex: number = Array.prototype.indexOf.call(
|
||||||
|
dropElement.parentElement!.children,
|
||||||
|
this.source ? placeholderElement : sourceElement
|
||||||
|
);
|
||||||
|
const dropIndex: number = Array.prototype.indexOf.call(
|
||||||
|
dropElement.parentElement!.children,
|
||||||
|
dropElement
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!this.source) {
|
||||||
|
this.sourceIndex = dragIndex;
|
||||||
|
this.source = item.dropContainer;
|
||||||
|
|
||||||
|
placeholderElement.style.width = this.boxWidth + 'px';
|
||||||
|
placeholderElement.style.height = this.boxHeight + 40 + 'px';
|
||||||
|
|
||||||
|
sourceElement.parentElement!.removeChild(sourceElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.targetIndex = dropIndex;
|
||||||
|
this.target = container;
|
||||||
|
this.dragRef = item._dragRef;
|
||||||
|
|
||||||
|
placeholderElement.style.display = '';
|
||||||
|
|
||||||
|
dropElement.parentElement!.insertBefore(
|
||||||
|
placeholderElement,
|
||||||
|
dropIndex > dragIndex ? dropElement.nextSibling : dropElement
|
||||||
|
);
|
||||||
|
|
||||||
|
this.placeholder._dropListRef.enter(
|
||||||
|
item._dragRef,
|
||||||
|
item.element.nativeElement.offsetLeft,
|
||||||
|
item.element.nativeElement.offsetTop
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user