a somewhat working example of a dashboard
This commit is contained in:
@@ -1,58 +1,110 @@
|
||||
<style>
|
||||
.grid-container {
|
||||
margin: 10px;
|
||||
.example-list {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.dashboard-card {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
.example-list li {
|
||||
display: table-cell;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.more-button {
|
||||
float: right;
|
||||
font-size: 2em;
|
||||
.example-container {
|
||||
display: flex;
|
||||
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;
|
||||
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 {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
padding-right: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.cdk-drag-preview {
|
||||
box-sizing: border-box;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.cdk-drag-animating {
|
||||
transition: unset;
|
||||
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-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>
|
||||
<div class="grid-container" style="height: 615px; overflow: hidden;">
|
||||
<mat-grid-list cols="8" rowHeight="1:1" gutterSize="15px">
|
||||
<mat-grid-tile *ngFor="let card of cards; let i = index;"
|
||||
[colspan]="card.cols" [rowspan]="card.rows">
|
||||
<cdk-drop-list [cdkDropListConnectedTo]="drops" [cdkDropListData]="i" >
|
||||
<mat-card cdkDrag (cdkDragEntered)="entered($event)" [cdkDragData]="i"
|
||||
class="dashboard-card" [style.backgroundColor]="card.color">
|
||||
<mat-icon cdkDragHandle class="more-button">drag_handle</mat-icon>
|
||||
<mat-card-content class="dashboard-card-content">
|
||||
<h1>{{card.title}}</h1>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</cdk-drop-list>
|
||||
</mat-grid-tile>
|
||||
</mat-grid-list>
|
||||
<h1>Drag&Drop with a flex-wrap</h1>
|
||||
|
||||
<button (click)="add()">Add</button>
|
||||
<button (click)="shuffle()">Shuffle</button>
|
||||
|
||||
<br />
|
||||
|
||||
<ul class="example-list">
|
||||
<li *ngFor="let item of items">{{ item }}</li>
|
||||
</ul>
|
||||
|
||||
<div
|
||||
class="example-container"
|
||||
cdkDropListGroup
|
||||
[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>
|
||||
@@ -1,111 +1,119 @@
|
||||
import { Component, QueryList, ViewChildren } from '@angular/core';
|
||||
import {CdkDragDrop, CdkDragEnter, CdkDropList, moveItemInArray, transferArrayItem} from '@angular/cdk/drag-drop';
|
||||
import { Component } from '@angular/core';
|
||||
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({
|
||||
selector: 'app-customizable-grid',
|
||||
templateUrl: './customizable-grid.component.html'
|
||||
})
|
||||
export class CustomizableGridComponent {
|
||||
entered($event: CdkDragEnter) {
|
||||
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);
|
||||
}
|
||||
export class CustomizableGridComponent implements AfterViewInit {
|
||||
@ViewChild(CdkDropList) placeholder!: CdkDropList;
|
||||
|
||||
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(){
|
||||
|
||||
}
|
||||
|
||||
@ViewChildren(CdkDropList) dropsQuery!: QueryList<CdkDropList>;
|
||||
|
||||
drops!: CdkDropList[];
|
||||
boxWidth = '200px';
|
||||
boxHeight = '200px';
|
||||
|
||||
ngAfterViewInit() {
|
||||
this.dropsQuery.changes.subscribe(() => {
|
||||
this.drops = this.dropsQuery.toArray()
|
||||
})
|
||||
Promise.resolve().then(() => {
|
||||
this.drops = this.dropsQuery.toArray();
|
||||
console.log(this.drops);
|
||||
})
|
||||
const placeholderElement = this.placeholder.element.nativeElement;
|
||||
|
||||
placeholderElement.style.display = 'none';
|
||||
placeholderElement.parentNode!.removeChild(placeholderElement);
|
||||
}
|
||||
|
||||
/** Based on the screen size, switch from standard to one column per row */
|
||||
cards = [
|
||||
{ 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() },
|
||||
{ title: 'Card 4', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 5', cols: 1, rows: 1, color: getColor() },
|
||||
{ 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() },
|
||||
{ title: 'Card 10', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 11', cols: 1, rows: 1, color: getColor() },
|
||||
{ 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() },
|
||||
{ title: 'Card 15', cols: 1, rows: 2, color: getColor() },
|
||||
{ title: 'Card 16', cols: 2, rows: 1, color: getColor() },
|
||||
{ title: 'Card 17', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 18', cols: 2, rows: 1, color: getColor() },
|
||||
{ title: 'Card 19', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 20', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 21', cols: 1, rows: 1, color: getColor()},
|
||||
/* { title: 'Card 22', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 23', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 24', cols: 1, rows: 1, color: getColor() },
|
||||
{ title: 'Card 25', cols: 1, rows: 1, color: getColor() },
|
||||
{ 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() },
|
||||
{ title: 'Card 29', cols: 1, rows: 1, color: getColor() } */
|
||||
];
|
||||
add() {
|
||||
this.items.push(this.items.length + 1);
|
||||
}
|
||||
|
||||
shuffle() {
|
||||
this.items.sort(function () {
|
||||
return 0.5 - Math.random();
|
||||
});
|
||||
}
|
||||
|
||||
onDropListDropped() {
|
||||
if (!this.target) {
|
||||
return;
|
||||
}
|
||||
|
||||
const placeholderElement: HTMLElement =
|
||||
this.placeholder.element.nativeElement;
|
||||
const placeholderParentElement: HTMLElement =
|
||||
placeholderElement.parentElement!;
|
||||
|
||||
placeholderElement.style.display = 'none';
|
||||
|
||||
placeholderParentElement.removeChild(placeholderElement);
|
||||
placeholderParentElement.appendChild(placeholderElement);
|
||||
placeholderParentElement.insertBefore(
|
||||
this.source!.element.nativeElement,
|
||||
placeholderParentElement.children[this.sourceIndex]
|
||||
);
|
||||
|
||||
if (this.placeholder._dropListRef.isDragging() && this.dragRef != null) {
|
||||
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