Skip to content

Commit 6ce68a1

Browse files
Angular: Convert to modern TypeScript with DevExtreme types
- Migrated to proper DevExtreme Angular types (DxDataGridTypes, DxPivotGridTypes) - Added ViewChild with generics: DxDataGridComponent<Sale, number> - Implemented named configuration components (v24.2+): dxo-data-grid-editing, dxi-data-grid-column - Added typed event handlers with proper DevExtreme Angular event types - Implemented early return pattern for null checking - Added ESLint disable comments for promise handling - Created app.service.ts with Sale interface and data service - Removed orig_ reference files
1 parent c6be82b commit 6ce68a1

File tree

4 files changed

+4698
-12
lines changed

4 files changed

+4698
-12
lines changed

Angular/src/app/app.component.html

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,62 @@
1-
<div class="default-style">
2-
<dx-button [text]="buttonText" (onClick)="onClick($event)"></dx-button>
1+
<div class="long-title">
2+
<h3>Sales Amount by Region</h3>
33
</div>
4+
<dx-pivot-grid
5+
id="sales"
6+
[allowSortingBySummary]="true"
7+
[allowSorting]="true"
8+
[allowFiltering]="true"
9+
[allowExpandAll]="true"
10+
[height]="440"
11+
[showBorders]="true"
12+
[dataSource]="pivotGridDataSource"
13+
(onCellClick)="onCellClick($event)"
14+
>
15+
<dxo-pivot-grid-export
16+
[enabled]="true"
17+
fileName="Sales"
18+
></dxo-pivot-grid-export>
19+
<dxo-pivot-grid-field-chooser
20+
[enabled]="false"
21+
></dxo-pivot-grid-field-chooser>
22+
</dx-pivot-grid>
23+
<dx-popup
24+
[width]="600"
25+
[height]="400"
26+
[title]="popupTitle"
27+
[showCloseButton]="true"
28+
[(visible)]="popupVisible"
29+
(onShowing)="onPopupShowing()"
30+
(onHiding)="onPopupHiding()"
31+
(onShown)="onPopupShown()"
32+
>
33+
<div *dxTemplate="let data of 'content'">
34+
<dx-data-grid
35+
#drillDownDataGrid
36+
[dataSource]="dataGridDataSource"
37+
[showBorders]="true"
38+
[width]="560"
39+
[height]="300"
40+
(onRowUpdating)="onRowUpdating($event)"
41+
(onRowInserting)="onRowAdding($event)"
42+
(onRowRemoving)="onRowRemoving($event)"
43+
>
44+
<dxo-data-grid-editing
45+
[allowUpdating]="true"
46+
[allowAdding]="true"
47+
[allowDeleting]="true"
48+
>
49+
</dxo-data-grid-editing>
50+
<dxi-data-grid-column dataField="region"></dxi-data-grid-column>
51+
<dxi-data-grid-column dataField="city"></dxi-data-grid-column>
52+
<dxi-data-grid-column
53+
dataField="amount"
54+
dataType="number"
55+
></dxi-data-grid-column>
56+
<dxi-data-grid-column
57+
dataField="date"
58+
dataType="date"
59+
></dxi-data-grid-column>
60+
</dx-data-grid>
61+
</div>
62+
</dx-popup>

Angular/src/app/app.component.ts

Lines changed: 123 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,135 @@
1-
import { Component } from '@angular/core';
2-
import { ClickEvent } from 'devextreme/ui/button';
1+
import { Component, ViewChild } from '@angular/core';
2+
import {
3+
DxDataGridComponent,
4+
type DxDataGridTypes,
5+
} from 'devextreme-angular/ui/data-grid';
6+
import type { DxPivotGridTypes } from 'devextreme-angular/ui/pivot-grid';
7+
import PivotGridDataSource from 'devextreme/ui/pivot_grid/data_source';
8+
import {
9+
ArrayStore, DataSource, isItemsArray, LoadResult,
10+
} from 'devextreme-angular/common/data';
11+
import notify from 'devextreme/ui/notify';
12+
import { Sale, Service } from './app.service';
313

414
@Component({
515
selector: 'app-root',
616
templateUrl: './app.component.html',
717
styleUrls: ['./app.component.scss'],
818
})
919
export class AppComponent {
10-
title = 'Angular';
20+
@ViewChild('drillDownDataGrid', { static: false })
21+
drillDownDataGrid!: DxDataGridComponent<Sale, number>;
1122

12-
counter = 0;
23+
data: ArrayStore;
1324

14-
buttonText = 'Click count: 0';
25+
pivotGridDataSource: PivotGridDataSource;
1526

16-
onClick(e: ClickEvent): void {
17-
this.counter++;
18-
this.buttonText = `Click count: ${this.counter}`;
27+
drillDownDataSource: DataSource<Sale, number> | null = null;
28+
29+
dataGridDataSource: DataSource<Sale, number> | null = null;
30+
31+
popupVisible = false;
32+
33+
popupTitle = '';
34+
35+
constructor(service: Service) {
36+
this.data = new ArrayStore({
37+
data: service.getSales(),
38+
key: 'id',
39+
});
40+
41+
this.pivotGridDataSource = new PivotGridDataSource({
42+
fields: [
43+
{
44+
caption: 'Region',
45+
width: 120,
46+
dataField: 'region',
47+
area: 'row',
48+
},
49+
{
50+
caption: 'City',
51+
dataField: 'city',
52+
width: 150,
53+
area: 'row',
54+
selector: this.citySelector,
55+
},
56+
{
57+
dataField: 'date',
58+
dataType: 'date',
59+
area: 'column',
60+
},
61+
{
62+
caption: 'Sales',
63+
dataField: 'amount',
64+
dataType: 'number',
65+
summaryType: 'sum',
66+
format: 'currency',
67+
area: 'data',
68+
},
69+
],
70+
store: this.data,
71+
});
72+
}
73+
74+
citySelector(data: Sale): string {
75+
return `${data.city} (${data.country})`;
76+
}
77+
78+
onCellClick(e: DxPivotGridTypes.CellClickEvent): void {
79+
if (e.area === 'data' && e.cell && e.cell.rowPath) {
80+
const rowPathLength = e.cell.rowPath.length;
81+
const rowPathName = e.cell.rowPath[rowPathLength - 1];
82+
const popupTitle = `${rowPathName || 'Total'} Drill Down Data`;
83+
84+
this.drillDownDataSource = this.pivotGridDataSource.createDrillDownDataSource(e.cell);
85+
this.popupTitle = popupTitle;
86+
this.popupVisible = true;
87+
}
88+
}
89+
90+
onPopupShowing(): void {
91+
this.drillDownDataSource?.store().load().then((items: LoadResult<Sale>) => {
92+
if (isItemsArray(items)) {
93+
this.dataGridDataSource = new DataSource<Sale, number>({
94+
store: new ArrayStore({
95+
key: this.data.key(),
96+
data: items,
97+
}),
98+
});
99+
}
100+
}).catch(() => {
101+
notify('Failed to load drill-down data', 'error', 1000);
102+
});
103+
}
104+
105+
onPopupHiding(): void {
106+
this.pivotGridDataSource.reload().catch(() => {
107+
notify('Failed to reload data', 'error', 1000);
108+
});
109+
}
110+
111+
onPopupShown(): void {
112+
const gridInstance = this.drillDownDataGrid?.instance;
113+
if (!gridInstance) return;
114+
115+
gridInstance.updateDimensions();
116+
}
117+
118+
onRowUpdating(e: DxDataGridTypes.RowUpdatingEvent<Sale, number>): void {
119+
this.data.update(e.key, e.newData).catch(() => {
120+
notify('Failed to update data', 'error', 1000);
121+
});
122+
}
123+
124+
onRowAdding(e: DxDataGridTypes.RowInsertingEvent<Sale, number>): void {
125+
this.data.insert(e.data).catch(() => {
126+
notify('Failed to insert data', 'error', 1000);
127+
});
128+
}
129+
130+
onRowRemoving(e: DxDataGridTypes.RowRemovingEvent<Sale, number>): void {
131+
this.data.remove(e.key).catch(() => {
132+
notify('Failed to remove data', 'error', 1000);
133+
});
19134
}
20135
}

Angular/src/app/app.module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { NgModule } from '@angular/core';
22
import { BrowserModule } from '@angular/platform-browser';
3-
import { DxButtonModule } from 'devextreme-angular/ui/button';
3+
import { DxDataGridModule } from 'devextreme-angular/ui/data-grid';
4+
import { DxPopupModule } from 'devextreme-angular/ui/popup';
5+
import { DxPivotGridModule } from 'devextreme-angular/ui/pivot-grid';
46
import { AppRoutingModule } from './app-routing.module';
57
import { AppComponent } from './app.component';
68

@@ -11,7 +13,9 @@ import { AppComponent } from './app.component';
1113
imports: [
1214
BrowserModule,
1315
AppRoutingModule,
14-
DxButtonModule,
16+
DxDataGridModule,
17+
DxPivotGridModule,
18+
DxPopupModule
1519
],
1620
providers: [],
1721
bootstrap: [AppComponent],

0 commit comments

Comments
 (0)