Skip to content

Commit d8333c5

Browse files
Update to DevExtreme 25.1.3 with TypeScript types and service architecture
1 parent 0ac0c86 commit d8333c5

39 files changed

+2466
-2327
lines changed

Angular/src/app/app.component.html

Lines changed: 76 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,77 @@
1-
<div class="default-style">
2-
<dx-button [text]="buttonText" (onClick)="onClick($event)"></dx-button>
1+
<div id="app-container">
2+
<dx-tree-list
3+
id="tree-list"
4+
[dataSource]="employees"
5+
[rootValue]="-1"
6+
keyExpr="ID"
7+
parentIdExpr="HeadID"
8+
[autoExpandAll]="expanded"
9+
[(expandedRowKeys)]="expandedRowKeys"
10+
[allowColumnReordering]="true"
11+
[allowColumnResizing]="true"
12+
[columnAutoWidth]="true"
13+
(onSelectionChanged)="selectEmployee($event)"
14+
>
15+
<dxi-column dataField="FullName" [fixed]="true">
16+
<dxi-validation-rule type="required"></dxi-validation-rule>
17+
</dxi-column>
18+
<dxi-column dataField="Position">
19+
<dxi-validation-rule type="required"></dxi-validation-rule>
20+
</dxi-column>
21+
<dxi-column dataField="BirthDate" dataType="date" [width]="100">
22+
<dxi-validation-rule type="required"></dxi-validation-rule>
23+
</dxi-column>
24+
<dxi-column dataField="HireDate" dataType="date" [width]="100">
25+
<dxi-validation-rule type="required"></dxi-validation-rule>
26+
</dxi-column>
27+
<dxi-column dataField="City"></dxi-column>
28+
<dxi-column dataField="State">
29+
<dxi-validation-rule type="required"></dxi-validation-rule>
30+
</dxi-column>
31+
<dxi-column dataField="Email" [visible]="false"></dxi-column>
32+
<dxi-column dataField="MobilePhone"></dxi-column>
33+
<dxi-column dataField="Skype"></dxi-column>
34+
35+
<dxo-column-fixing [enabled]="true"></dxo-column-fixing>
36+
<dxo-column-chooser [enabled]="true"></dxo-column-chooser>
37+
<dxo-filter-row [visible]="true"></dxo-filter-row>
38+
<dxo-search-panel [visible]="true"></dxo-search-panel>
39+
<dxo-selection mode="single"></dxo-selection>
40+
<dxo-editing
41+
mode="popup"
42+
[allowUpdating]="true"
43+
[allowDeleting]="true"
44+
[allowAdding]="true"
45+
>
46+
</dxo-editing>
47+
48+
<dxo-toolbar>
49+
<dxi-item location="after">
50+
<dx-button
51+
[text]="expanded ? 'Collapse All' : 'Expand All'"
52+
[width]="136"
53+
(onClick)="toggleExpansion()"
54+
>
55+
</dx-button>
56+
</dxi-item>
57+
<dxi-item name="addRowButton" showText="always"></dxi-item>
58+
<dxi-item name="exportButton"></dxi-item>
59+
<dxi-item name="columnChooserButton"></dxi-item>
60+
<dxi-item name="searchPanel"></dxi-item>
61+
</dxo-toolbar>
62+
63+
<dxo-row-dragging
64+
[onDragChange]="onDragChange"
65+
[onReorder]="onReorder"
66+
[allowDropInsideItem]="true"
67+
[allowReordering]="true"
68+
>
69+
</dxo-row-dragging>
70+
71+
<dxo-paging [enabled]="true" [pageSize]="10"> </dxo-paging>
72+
</dx-tree-list>
73+
74+
<p id="selected-employee" *ngIf="selectedEmployee">
75+
Selected employee: {{ selectedEmployee.FullName }}
76+
</p>
377
</div>

Angular/src/app/app.component.scss

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
.default-style {
2-
margin: 50px;
3-
width: 90vw;
1+
#app-container {
2+
width: 900px;
3+
position: relative;
4+
margin: 50px auto;
5+
padding: 20px;
6+
border: 1px solid #ddd;
7+
}
8+
9+
#tree-list {
10+
margin-bottom: 20px;
11+
}
12+
13+
#selected-employee {
14+
margin-top: 20px;
15+
font-weight: bold;
16+
color: #337ab7;
417
}

Angular/src/app/app.component.ts

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,88 @@
11
import { Component } from '@angular/core';
2-
import { ClickEvent } from 'devextreme/ui/button';
2+
import {
3+
Employee,
4+
DragChangeEvent,
5+
ReorderEvent,
6+
SelectionChangedEvent,
7+
} from './app.types';
8+
import { EmployeesService } from './employees.service';
39

410
@Component({
511
selector: 'app-root',
612
templateUrl: './app.component.html',
713
styleUrls: ['./app.component.scss'],
814
})
915
export class AppComponent {
10-
title = 'Angular';
16+
employees: Employee[] = [];
1117

12-
counter = 0;
18+
selectedEmployee: Employee | null = null;
1319

14-
buttonText = 'Click count: 0';
20+
expanded = true;
1521

16-
onClick(e: ClickEvent): void {
17-
this.counter++;
18-
this.buttonText = `Click count: ${this.counter}`;
22+
expandedRowKeys: number[] = [];
23+
24+
constructor(private readonly employeesService: EmployeesService) {
25+
this.employees = this.employeesService.getEmployees();
26+
this.selectEmployee = this.selectEmployee.bind(this);
27+
this.onReorder = this.onReorder.bind(this);
28+
this.onDragChange = this.onDragChange.bind(this);
29+
}
30+
31+
selectEmployee(e: SelectionChangedEvent): void {
32+
e.component.byKey(e.currentSelectedRowKeys[0]).then((employee: Employee) => {
33+
if (employee) {
34+
this.selectedEmployee = employee;
35+
}
36+
}).catch(() => {
37+
// Handle error silently
38+
});
39+
}
40+
41+
onDragChange(e: DragChangeEvent): void {
42+
const visibleRows = e.component.getVisibleRows();
43+
const sourceNode = e.component.getNodeByKey(e.itemData.ID);
44+
let targetNode = visibleRows[e.toIndex].node;
45+
46+
while (targetNode?.data) {
47+
if (targetNode.data.ID === sourceNode.data.ID) {
48+
e.cancel = true;
49+
break;
50+
}
51+
const parentNode = targetNode.parent;
52+
if (!parentNode) {
53+
break;
54+
}
55+
targetNode = parentNode;
56+
}
57+
}
58+
59+
onReorder(e: ReorderEvent): void {
60+
const visibleRows = e.component.getVisibleRows();
61+
const sourceData = e.itemData;
62+
const targetData = visibleRows[e.toIndex].data;
63+
64+
if (e.dropInsideItem) {
65+
e.itemData.HeadID = targetData.ID;
66+
e.component.refresh().catch(() => {
67+
// Handle error silently
68+
});
69+
} else {
70+
let targetIndex = this.employees.indexOf(targetData);
71+
72+
if (sourceData.HeadID !== targetData.HeadID) {
73+
sourceData.HeadID = targetData.HeadID;
74+
if (e.toIndex > e.fromIndex) {
75+
targetIndex += 1;
76+
}
77+
}
78+
79+
this.employeesService.reorderEmployees(sourceData, targetIndex);
80+
this.employees = this.employeesService.getEmployees();
81+
}
82+
}
83+
84+
toggleExpansion(): void {
85+
this.expanded = !this.expanded;
86+
this.expandedRowKeys = [];
1987
}
2088
}

Angular/src/app/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NgModule } from '@angular/core';
22
import { BrowserModule } from '@angular/platform-browser';
3+
import { DxTreeListModule } from 'devextreme-angular/ui/tree-list';
34
import { DxButtonModule } from 'devextreme-angular/ui/button';
45
import { AppRoutingModule } from './app-routing.module';
56
import { AppComponent } from './app.component';
@@ -11,6 +12,7 @@ import { AppComponent } from './app.component';
1112
imports: [
1213
BrowserModule,
1314
AppRoutingModule,
15+
DxTreeListModule,
1416
DxButtonModule,
1517
],
1618
providers: [],

Angular/src/app/app.types.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { DxTreeListTypes } from 'devextreme-angular/ui/tree-list';
2+
3+
export interface Employee {
4+
ID: number;
5+
HeadID: number;
6+
FullName: string;
7+
Position: string;
8+
City: string;
9+
State: string;
10+
Email: string;
11+
Skype: string;
12+
MobilePhone: string;
13+
BirthDate: string;
14+
HireDate: string;
15+
}
16+
17+
export type DragChangeEvent = DxTreeListTypes.RowDraggingChangeEvent;
18+
export type ReorderEvent = DxTreeListTypes.RowDraggingReorderEvent;
19+
export type SelectionChangedEvent = DxTreeListTypes.SelectionChangedEvent;

0 commit comments

Comments
 (0)