Skip to content

Commit

Permalink
Dashboard V2 (#182)
Browse files Browse the repository at this point in the history
* Implement grid based dashboard and limit view widths

* Remove relics from old dashboard

* Translate drag to remove message

* Some refactoring
  • Loading branch information
hchris1 authored Jul 7, 2024
1 parent 4ead633 commit ce95fa0
Show file tree
Hide file tree
Showing 44 changed files with 7,026 additions and 980 deletions.
9 changes: 6 additions & 3 deletions angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,22 @@
"abp-ng2-module": "10.0.0",
"abp-web-resources": "^5.9.1",
"admin-lte-css-only": "^3.2.0",
"apexcharts": "^3.49.2",
"apexcharts": "^3.50.0",
"core-js": "^3.37.1",
"famfamfam-flags": "^1.0.0",
"gridstack": "^10.3.0",
"jquery": "^3.7.1",
"lodash-es": "^4.17.21",
"moment": "^2.30.1",
"moment-timezone": "^0.5.45",
"ng-apexcharts": "^1.11.0",
"ngx-bootstrap": "^18.0.0",
"ngx-markdown": "^18.0.0",
"ngx-pagination": "^6.0.3",
"ngx-toastr": "19.0.0",
"push.js": "1.0.12",
"rxjs": "^7.8.1",
"sweetalert2": "^11.12.1",
"sweetalert2": "^11.12.2",
"ts-helpers": "^1.1.2",
"tslib": "^2.6.3",
"zone.js": "~0.14.7"
Expand All @@ -57,7 +60,7 @@
"@angularclass/hmr": "^3.0.0",
"@types/jasmine": "~5.1.4",
"@types/lodash-es": "^4.17.12",
"@types/node": "20.14.9",
"@types/node": "20.14.10",
"@typescript-eslint/eslint-plugin": "7.15.0",
"@typescript-eslint/parser": "7.15.0",
"eslint-plugin-import": "^2.29.1",
Expand Down
1,078 changes: 1,031 additions & 47 deletions angular/pnpm-lock.yaml

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions angular/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {PaginationModule} from 'ngx-bootstrap/pagination';
import {TooltipModule} from 'ngx-bootstrap/tooltip';
import {AlertModule} from 'ngx-bootstrap/alert';
import {ProgressbarModule} from 'ngx-bootstrap/progressbar';
import {GridstackModule} from 'gridstack/dist/angular';
import {MarkdownModule} from 'ngx-markdown';

// tenants
import {TenantsComponent} from '@app/tenants/tenants.component';
Expand Down Expand Up @@ -106,6 +108,7 @@ import {StatusTablePanelComponent} from './status/status-table/status-table-pane
import {StatisticsComponent} from './statistics/statistics.component';
import {StatisticsTileComponent} from './statistics/statistics-tile/statistics-tile.component';
import {StatusChipSectionComponent} from './status/status-chip/status-chip.component';
import {MarkdownTileComponent} from './dashboard/custom-dashboard/dashboard-tile/markdown-tile/markdown-tile.component';

@NgModule({
declarations: [
Expand Down Expand Up @@ -197,6 +200,7 @@ import {StatusChipSectionComponent} from './status/status-chip/status-chip.compo
StatisticsComponent,
StatisticsTileComponent,
StatusChipSectionComponent,
MarkdownTileComponent,
],
imports: [
CommonModule,
Expand All @@ -219,6 +223,8 @@ import {StatusChipSectionComponent} from './status/status-chip/status-chip.compo
TooltipModule,
AlertModule.forRoot(),
ProgressbarModule.forRoot(),
GridstackModule,
MarkdownModule.forRoot(),
],
providers: [],
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div
class="card h-100 {{ getCardOutlineClass(asset) }}"
class="card {{ getCardOutlineClass(asset) }} h-100"
style="cursor: pointer"
(click)="onAssetClick(asset)"
*ngIf="asset"
Expand Down Expand Up @@ -36,7 +36,7 @@
style="max-height: 8rem; min-height: 8rem"
></app-asset-image-carousel>
</div>
<div class="card-footer" *ngIf="showPackages">
<div class="card-footer" *ngIf="showPackages" style="flex-grow: 1">
<div class="row">
<div
class="col-auto"
Expand Down
11 changes: 8 additions & 3 deletions angular/src/app/asset/asset-summary/asset-summary.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
Criticality,
PackageDto,
} from '@shared/service-proxies/service-proxies';
import {Subscription} from 'rxjs';
import {debounceTime, filter, Subscription} from 'rxjs';

@Component({
selector: 'app-asset-summary',
Expand Down Expand Up @@ -51,8 +51,13 @@ export class AssetSummaryComponent
}

ngOnInit(): void {
this.statusChangeSubscription =
this._comonHubService.statusUpdate.subscribe(update => {
this.statusChangeSubscription = this._comonHubService.statusUpdate
.pipe(
filter(update => update.assetId === this.assetId),
// Prevent lots of requests when multiple packages are updated at the same time
debounceTime(500)
)
.subscribe(update => {
if (this.assetId === update.assetId) {
this.loadAsset();
}
Expand Down
4 changes: 2 additions & 2 deletions angular/src/app/asset/asset.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div [@routerTransition] *ngIf="asset">
<div [@routerTransition] *ngIf="asset" class="view-container">
<section class="content-header">
<div class="container-fluid">
<div class="row">
Expand Down Expand Up @@ -179,7 +179,7 @@ <h3 class="col">📦 {{ 'Assets.PackagesTitle' | localize }}</h3>

<div class="row pt-3">
<div
class="col-xl-4 col-md-6 col-12"
class="col-xl-4 col-md-6 col-12 pb-2"
*ngFor="let package of asset.packages"
>
<app-package-preview
Expand Down
2 changes: 1 addition & 1 deletion angular/src/app/common/no-data/no-data.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {NoDataImage} from '@shared/enums/NoDataImage';
templateUrl: './no-data.component.html',
})
export class NoDataComponent {
@Input() message: string = 'No data available'; // TODO: Use a translation key
@Input() message: string = 'NoDataAvailable';
@Input() width: number = 7;
@Input() image: NoDataImage = NoDataImage.PersonWithStatus;
}
Original file line number Diff line number Diff line change
@@ -1,51 +1,27 @@
<div class="container-fluid">
<div class="row pr-3" style="justify-content: right">
<button
type="button"
class="col-1 btn btn-circle btn-link"
(click)="moveUp()"
*ngIf="editMode && !isFirst"
>
<i class="fa-solid fa-arrow-up"></i>
</button>
<button
type="button"
class="col-1 btn btn-circle btn-link"
(click)="moveDown()"
*ngIf="editMode && !isLast"
>
<i class="fa-solid fa-arrow-down"></i>
</button>
<button
type="button"
class="col-1 btn btn-circle btn-link"
(click)="deleteTileClicked()"
*ngIf="editMode"
>
<i class="fa-solid fa-trash"></i>
</button>
</div>
</div>

<div class="container-fluid">
<app-package-preview
*ngIf="isPackageTile()"
[packageId]="tile.itemId"
[showDate]="false"
[showPath]="true"
></app-package-preview>
<app-asset-summary
*ngIf="isAssetTile()"
[assetId]="tile.itemId"
[showImage]="false"
[showPackages]="false"
[showPath]="true"
(assetClicked)="routeToAsset()"
></app-asset-summary>
<app-group-summary
*ngIf="isGroupTile()"
[groupId]="tile.itemId"
[showPath]="true"
(groupClicked)="routeToGroup()"
></app-group-summary>
</div>
<app-package-preview
*ngIf="isPackageTile()"
[packageId]="tile.itemId"
[showDate]="false"
[showPath]="true"
[showTimeline]="tile.height > 2"
></app-package-preview>
<app-asset-summary
*ngIf="isAssetTile()"
[assetId]="tile.itemId"
[showImage]="tile.height > 6"
[showPackages]="tile.height > 2"
[showPath]="true"
(assetClicked)="routeToAsset()"
></app-asset-summary>
<app-group-summary
*ngIf="isGroupTile()"
[groupId]="tile.itemId"
[showPath]="true"
(groupClicked)="routeToGroup()"
></app-group-summary>
<app-markdown-tile
*ngIf="isMarkdownTile()"
[dashboardId]="dashboardId"
[editMode]="editMode"
[tile]="tile"
></app-markdown-tile>
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import {Component, EventEmitter, Injector, Input, Output} from '@angular/core';
import {Component, Injector, Input} from '@angular/core';
import {Router} from '@angular/router';
import {AppComponentBase} from '@shared/app-component-base';
import {
DashboardServiceProxy,
DashboardTileDto,
} from '@shared/service-proxies/service-proxies';
import {Subscription} from 'rxjs';
import {DashboardTileDto} from '@shared/service-proxies/service-proxies';

@Component({
selector: 'app-dashboard-tile',
Expand All @@ -15,59 +11,14 @@ export class DashboardTileComponent extends AppComponentBase {
@Input() dashboardId: number;
@Input() tile: DashboardTileDto;
@Input() editMode: boolean = false;
@Input() isFirst: boolean = false;
@Input() isLast: boolean = false;

@Output() tileDeleted = new EventEmitter<DashboardTileDto>();
@Output() tileMoved = new EventEmitter<DashboardTileDto>();

statusChangeSubscription: Subscription;
connectionEstablishedSubscription: Subscription;

constructor(
private _dashboardService: DashboardServiceProxy,
private _router: Router,
injector: Injector
) {
super(injector);
}

moveUp() {
this._dashboardService
.moveTileUp(this.dashboardId, this.tile.id)
.subscribe(() => {
this.tileMoved.emit(this.tile);
});
}

moveDown() {
this._dashboardService
.moveTileDown(this.dashboardId, this.tile.id)
.subscribe(() => {
this.tileMoved.emit(this.tile);
});
}

deleteTileClicked() {
this.message.confirm(
this.l('Dashboard.TileDeleteConfirmationMessage'),
this.l('Dashboard.TileDeleteConfirmationTitle'),
isConfirmed => {
if (isConfirmed) {
this._dashboardService
.deleteTile(this.dashboardId, this.tile.id)
.subscribe(() => {
this.tileDeleted.emit(this.tile);
this.notify.success(
this.l('Dashboard.TileDeleteSuccessMessage'),
this.l('Dashboard.TileDeleteSuccessTitle')
);
});
}
}
);
}

isGroupTile() {
return this.tile.itemType === 0;
}
Expand All @@ -80,6 +31,10 @@ export class DashboardTileComponent extends AppComponentBase {
return this.tile.itemType === 2;
}

isMarkdownTile() {
return this.tile.itemType === 3;
}

routeToAsset() {
this._router.navigate(['/app/overview/assets', this.tile.itemId]);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<textarea
*ngIf="editMode"
style="width: 100%; height: 100%"
class="form-control"
[(ngModel)]="markdown"
></textarea>

<div class="card card-body h-100" *ngIf="!editMode">
<markdown style="overflow: auto">{{ markdown }}</markdown>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import {
Component,
Injector,
Input,
OnChanges,
OnInit,
SimpleChanges,
} from '@angular/core';
import {AppComponentBase} from '@shared/app-component-base';
import {
DashboardServiceProxy,
DashboardTileDto,
} from '@shared/service-proxies/service-proxies';

@Component({
selector: 'app-markdown-tile',
templateUrl: './markdown-tile.component.html',
})
export class MarkdownTileComponent
extends AppComponentBase
implements OnInit, OnChanges
{
@Input() dashboardId: number;
@Input() tile: DashboardTileDto;
@Input() editMode: boolean = false;

initialized = false;
markdown: string;

constructor(
injector: Injector,
private _dashboardService: DashboardServiceProxy
) {
super(injector);
}

ngOnInit() {
this.markdown = this.tile.content;
this.initialized = true;
}

ngOnChanges(changes: SimpleChanges) {
if (!this.initialized) return;

if (!!changes.editMode && changes.editMode.currentValue === false) {
if (this.markdown !== this.tile.content) {
this.tile.content = this.markdown;
this.saveMarkdown();
}
}
}

saveMarkdown() {
this._dashboardService
.updateTileContent(this.dashboardId, this.tile.id, this.markdown)
.subscribe();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import 'gridstack/dist/gridstack.min.css';
Loading

0 comments on commit ce95fa0

Please sign in to comment.