Skip to content

Commit

Permalink
feat(components): add dashboard module #INFR-6408 (#32)
Browse files Browse the repository at this point in the history
* feat: add dashboard module #INFR-6408

* feat(components): add dashboard module #INFR-6408

* feat(components): add dashboard module #INFR-6408

* feat(components): add dashboard module #INFR-6408

* feat(components): delete widget item and change dashboard params

* fix(components): fix build dashboard error

* fix: fix thyWidgetsChange

* fix: add itemRemovedCallback

* fix: delete ThyDashboardConfig and change buildTemporaryWidgets to buildWidgetItems

---------

Co-authored-by: walkerkay <[email protected]>
  • Loading branch information
HandsomeButterball and walkerkay authored Feb 14, 2023
1 parent 41ca28e commit 37512d5
Show file tree
Hide file tree
Showing 29 changed files with 486 additions and 11 deletions.
4 changes: 4 additions & 0 deletions .angulardoc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"repoId": "45733311-0044-4e35-b027-fca963421012",
"lastSync": 0
}
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,14 @@
"@angular/platform-browser": "^14.2.10",
"@angular/platform-browser-dynamic": "^14.2.10",
"@angular/router": "^14.2.10",
"@tethys/cdk": "^14.1.7",
"@tethys/cdk": "^14.2.11",
"@tethys/icons": "1.1.103",
"@tethys/store": "^11.0.0",
"@types/extend": "^3.0.1",
"angular-gridster2": "^14.1.4",
"date-fns": "^2.6.0",
"extend": "^3.0.2",
"ngx-tethys": "^14.1.7",
"ngx-tethys": "^14.2.16",
"rxjs": "~7.4.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
Expand Down
14 changes: 14 additions & 0 deletions packages/components/dashboard/dashboard.class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GridsterItem } from 'angular-gridster2';

export interface WidgetGridsterItem extends GridsterItem {
widget: ThyWidgetItem;
}

export interface ThyWidgetItem<TConfig = unknown> {
type: string;
size: { cols: number; rows: number };
position: { x: number; y: number };
name?: string;
_id?: string;
config?: TConfig;
}
5 changes: 5 additions & 0 deletions packages/components/dashboard/dashboard.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<gridster #gridster class="dashboard-gridster" [options]="config">
<gridster-item class="dashboard-girdster-item" [item]="gridsterItem" *ngFor="let gridsterItem of widgetGridsterItems; trackBy: trackBy">
<ng-container *thyViewOutlet="thyWidgetViews[gridsterItem.widget.type]; context: { widget: gridsterItem.widget }"> </ng-container>
</gridster-item>
</gridster>
56 changes: 56 additions & 0 deletions packages/components/dashboard/dashboard.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
@use '~ngx-tethys/styles/variables.scss';

.thy-dashboard {
.dashboard-gridster {
background-color: variables.$gray-80;

.dashboard-girdster-item {
border-radius: 2px;
outline: 1px solid variables.$gray-200;
padding: 24px 28px;
&.gridster-item-moving {
z-index: 2 !important;
}
.dashboard-girdster-item-resize-icon {
position: absolute;
right: 2px;
bottom: 2px;
color: variables.$gray-500;
visibility: hidden;
font-size: 10px;
}
&:hover {
box-shadow: 0 3px 6px 0 rgba(variables.$black, 0.04);
.dashboard-girdster-item-resize-icon {
visibility: visible;
}
.gridster-item-resizable-handler.handle-se {
border-color: transparent;
}
}
}
.gridster-column {
border-left: 1px dashed rgba(variables.$gray-500, 0.3);
border-right: 1px dashed rgba(variables.$gray-500, 0.3);
}
.gridster-row {
border-top: 1px dashed rgba(variables.$gray-500, 0.3);
border-bottom: 1px dashed rgba(variables.$gray-500, 0.3);
}

.gridster-preview {
background: rgba(0, 0, 0, 0.1);
}

&-editing {
}

.empty-block {
position: absolute;
height: 8px;
width: 100%;
left: 0;
right: 0;
}
}
}
133 changes: 133 additions & 0 deletions packages/components/dashboard/dashboard.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { EventEmitter, OnChanges, Output, SimpleChanges, Type, TemplateRef } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit, ViewChild } from '@angular/core';
import { CompactType, DisplayGrid, GridsterComponentInterface, GridsterConfig, GridsterItem, GridType } from 'angular-gridster2';
import { ThyWidgetItem, WidgetGridsterItem } from './dashboard.class';
import { ThyDashboardWidgetComponent } from './widget/widget.component';

@Component({
selector: 'thy-dashboard',
templateUrl: './dashboard.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
host: { class: 'thy-dashboard' }
})
export class ThyDashboardComponent implements OnInit, OnChanges {
/**
* 仪表盘部件对应组件或模版映射
*/
@Input() thyWidgetViews: Record<string, Type<ThyDashboardWidgetComponent> | TemplateRef<any>> = {};

/**
* 仪表盘部件是否允许拖拽
*/
@Input() thyDraggable: boolean = false;

/**
* 仪表盘部件数据
*/
@Input() set thyWidgets(value: ThyWidgetItem[]) {
this.widgetGridsterItems = this.buildWidgetGridsterItems(value);
}

/**
* 部件变更
*/
@Output() thyWidgetsChange: EventEmitter<ThyWidgetItem[]> = new EventEmitter();

public widgetGridsterItems: WidgetGridsterItem[] = [];

public config: GridsterConfig = {
gridType: GridType.VerticalFixed,
margin: 8,
compactType: CompactType.None,
displayGrid: DisplayGrid.None,
maxCols: 12,
minCols: 12,
fixedRowHeight: 120,
disableScrollHorizontal: true,
pushItems: true,
disablePushOnDrag: true,
useTransformPositioning: false,
// swapWhileDragging: true,
itemChangeCallback: () => {
const widgets = this.buildWidgetItems();
this.thyWidgetsChange.emit(widgets);
},
itemRemovedCallback: () => {
const widgets = this.buildWidgetItems();
this.thyWidgetsChange.emit(widgets);
}
};

@ViewChild('gridster')
gridsterComponent!: GridsterComponentInterface;

constructor(private cdr: ChangeDetectorRef) {}

ngOnInit(): void {
this.setDraggable(this.thyDraggable);
}

ngOnChanges(changes: SimpleChanges): void {
if (!changes.thyDraggable?.firstChange) {
this.setDraggable(this.thyDraggable);
}
}

trackBy(index: number, item: WidgetGridsterItem) {
return item.widget?._id || index;
}

private buildWidgetGridsterItems(widgets: ThyWidgetItem[]) {
return (widgets || []).map((widget) => {
const gridsterItem: WidgetGridsterItem = {
x: widget.position?.x,
y: widget.position?.y,
cols: widget.size.cols,
rows: widget.size.rows,
widget: widget
};

return gridsterItem;
});
}

private setDraggable(draggable: boolean) {
if (draggable) {
this.config = {
...this.config,
minRows: 12,
draggable: {
enabled: true
},
resizable: {
enabled: true
},
displayGrid: DisplayGrid.Always
};
} else {
this.config = {
...this.config,
minRows: 1,
draggable: {
enabled: false
},
resizable: {
enabled: false
},
displayGrid: DisplayGrid.None
};
}
this.cdr.markForCheck();
}

private buildWidgetItems() {
return (this.gridsterComponent.grid || []).map((gridsterItem) => {
const widgetGridsterItem = gridsterItem.item as WidgetGridsterItem;
return {
...widgetGridsterItem.widget,
position: { x: widgetGridsterItem.x, y: widgetGridsterItem.y },
size: { cols: widgetGridsterItem.cols, rows: widgetGridsterItem.rows }
};
});
}
}
15 changes: 15 additions & 0 deletions packages/components/dashboard/doc/zh-cn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
title: Dashboard
subtitle: 仪表盘
order: 10
---

<alert>仪表盘。</alert>

## 模块导入

```ts
import { ThyProDashboardModule } from '@tethys/pro/dashboard';
```

<examples />
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div class="dashboard-container">
<thy-dashboard #thyProDashboard [thyWidgets]="widgets" [thyWidgetViews]="widgetViews"></thy-dashboard>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.dashboard-container {
height: 800px;
border: 1px solid #eee;
}
46 changes: 46 additions & 0 deletions packages/components/dashboard/examples/basic/basic.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Component, OnInit, ViewChild } from '@angular/core';
import { ThyDashboardComponent } from '@tethys/pro/dashboard';
import { ThyDashboardBasicLinksWidgetComponent } from './widgets/links/links.component';
import { ThyDashboardBasicNoticeWidgetComponent } from './widgets/notice/notice.component';

@Component({
selector: 'thy-dashboard-basic-example',
templateUrl: './basic.component.html',
styleUrls: ['./basic.component.scss']
})
export class ThyDashboardBasicExampleComponent implements OnInit {
widgets = [
{
_id: '63c0d6f08e1cc40c3e41ad30',
name: '公告',
type: 'notice',
size: {
cols: 5,
rows: 3
}
},
{
_id: '63c0d6f08e1cc40c3e41ad30',
name: '链接',
type: 'links',
size: {
cols: 4,
rows: 3
}
}
];

widgetViews = {
notice: ThyDashboardBasicNoticeWidgetComponent,
links: ThyDashboardBasicLinksWidgetComponent
};

editing = false;

@ViewChild('thyDashboard')
dashboardComponent!: ThyDashboardComponent;

constructor() {}

ngOnInit(): void {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<thy-dashboard-widget-header thyTitle="链接" thyDescription="一些常用的链接"></thy-dashboard-widget-header>
<thy-dashboard-widget-body>
<a target="_blank" href="https://prophet.pingcode.com" class="ng-star-inserted">先知平台</a>
<br />
<a target="_blank" href="https://itsm.pingcode.top" class="ng-star-inserted">蓝鲸平台</a>
<br /><a target="_blank" href="https://sc.pingcode.com" class="ng-star-inserted">神策-PingCode </a>
</thy-dashboard-widget-body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component, OnInit } from '@angular/core';
import { ThyDashboardWidgetComponent, ThyWidgetItem } from '@tethys/pro/dashboard';

@Component({
selector: 'thy-dashboard-basic-links-widget',
templateUrl: './links.component.html'
})
export class ThyDashboardBasicLinksWidgetComponent extends ThyDashboardWidgetComponent implements OnInit {
constructor() {
super();
}

ngOnInit() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<thy-dashboard-widget-header thyTitle="公告" thyDescription=""></thy-dashboard-widget-header>
<thy-dashboard-widget-body>
欢迎使用 PingCode!PingCode
是简单易用的新一代研发管理平台,让研发管理自动化、数据化、智能化,帮助企业提升研发效能。从路线图到专业的敏捷开发管理,多项目进度跟踪,知识沉淀与测试管理;覆盖研发全流程,通过增量迭代,实现计划、研发和交付的可预测和可控制,有效连接需求规划、开发过程、测试和持续集成。
查看  PingCode 官网 ,全面了解 PingCode 产品。 查看  使用指南 ,了解如何快速通过 PingCode 开启高效研发。
</thy-dashboard-widget-body>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component, OnInit } from '@angular/core';
import { ThyDashboardWidgetComponent, ThyWidgetItem } from '@tethys/pro/dashboard';

@Component({
selector: 'thy-dashboard-basic-notice-widget',
templateUrl: './notice.component.html'
})
export class ThyDashboardBasicNoticeWidgetComponent extends ThyDashboardWidgetComponent implements OnInit {
constructor() {
super();
}

ngOnInit() {}
}
10 changes: 10 additions & 0 deletions packages/components/dashboard/examples/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { ThyButtonModule } from 'ngx-tethys/button';
import { ThyProDashboardModule } from '@tethys/pro/dashboard';
import { ThyDashboardBasicNoticeWidgetComponent } from './basic/widgets/notice/notice.component';
import { ThyDashboardBasicLinksWidgetComponent } from './basic/widgets/links/links.component';
import { ThySharedModule } from 'ngx-tethys/shared';

export default {
declarations: [ThyDashboardBasicNoticeWidgetComponent, ThyDashboardBasicLinksWidgetComponent],
imports: [ThyProDashboardModule, ThyButtonModule, ThySharedModule]
};
6 changes: 6 additions & 0 deletions packages/components/dashboard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './module';
export * from './dashboard.component';
export * from './widget/body/widget-body.component';
export * from './widget/header/widget-header.component';
export * from './widget/widget.component';
export * from './dashboard.class';
21 changes: 21 additions & 0 deletions packages/components/dashboard/module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ThySharedModule } from 'ngx-tethys/shared';
import { ThyActionModule } from 'ngx-tethys/action';
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { GridsterModule } from 'angular-gridster2';
import { ThyIconModule } from 'ngx-tethys/icon';
import { ThyTooltipModule } from 'ngx-tethys/tooltip';
import { ThyDashboardWidgetHeaderComponent } from './widget/header/widget-header.component';
import { ThyDashboardWidgetBodyComponent } from './widget/body/widget-body.component';
import { ThyDashboardComponent } from './dashboard.component';

const TETHYS_MODULES = [ThyTooltipModule, ThyIconModule, ThyActionModule, ThySharedModule];

@NgModule({
declarations: [ThyDashboardComponent, ThyDashboardWidgetHeaderComponent, ThyDashboardWidgetBodyComponent],
imports: [...TETHYS_MODULES, RouterModule, CommonModule, GridsterModule],
exports: [ThyDashboardComponent, ThyDashboardWidgetHeaderComponent, ThyDashboardWidgetBodyComponent],
providers: []
})
export class ThyProDashboardModule {}
5 changes: 5 additions & 0 deletions packages/components/dashboard/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"lib": {
"entryFile": "index.ts"
}
}
Loading

0 comments on commit 37512d5

Please sign in to comment.