Skip to content

Commit 9aba7f4

Browse files
committed
chore: add treeview demo
1 parent 95cdbab commit 9aba7f4

File tree

11 files changed

+291
-66
lines changed

11 files changed

+291
-66
lines changed
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { Component } from "@angular/core";
2-
import { RouterOutlet } from "@angular/router";
1+
import { Component } from '@angular/core';
2+
import { RouterOutlet } from '@angular/router';
33

44
@Component({
5-
selector: "app-root",
5+
selector: 'app-root',
66
imports: [RouterOutlet],
7-
templateUrl: "./app.component.html",
8-
styleUrl: "./app.component.css",
7+
templateUrl: './app.component.html',
8+
styleUrl: './app.component.css',
99
})
1010
export class AppComponent {}
Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,57 @@
1-
import { Routes } from "@angular/router";
1+
import { Routes } from '@angular/router';
22

33
export const routes: Routes = [
44
{
5-
path: "grid",
5+
path: 'grid',
66
loadComponent: () =>
7-
import("./components/dynamic-grid/dynamic-grid.component").then((m) => m.DynamicGridComponent),
7+
import('./components/dynamic-grid/dynamic-grid.component').then((m) => m.DynamicGridComponent),
88
},
99
{
10-
path: "scheduler",
11-
loadComponent: () => import("./components/scheduler/scheduler.component").then((m) => m.SchedulerComponent),
10+
path: 'scheduler',
11+
loadComponent: () => import('./components/scheduler/scheduler.component').then((m) => m.SchedulerComponent),
1212
},
1313
{
14-
path: "charts",
15-
loadComponent: () => import("./components/charts/charts.component").then((m) => m.ChartsComponent),
14+
path: 'charts',
15+
loadComponent: () => import('./components/charts/charts.component').then((m) => m.ChartsComponent),
1616
},
1717
{
18-
path: "header",
19-
loadComponent: () => import("./components/header/header.component").then((m) => m.HeaderComponent),
18+
path: 'header',
19+
loadComponent: () => import('./components/header/header.component').then((m) => m.HeaderComponent),
2020
},
2121
{
22-
path: "dateinputs",
22+
path: 'dateinputs',
2323
loadComponent: () =>
24-
import("./components/date-inputs/date-inputs.component").then((m) => m.DateInputsComponent),
24+
import('./components/date-inputs/date-inputs.component').then((m) => m.DateInputsComponent),
2525
},
2626
{
27-
path: "dropdowns",
28-
loadComponent: () => import("./components/dropdowns/dropdowns.component").then((m) => m.DropdownsComponent),
27+
path: 'dropdowns',
28+
loadComponent: () => import('./components/dropdowns/dropdowns.component').then((m) => m.DropdownsComponent),
2929
},
3030
{
31-
path: "layout",
32-
loadComponent: () => import("./components/layout/my-layout.component").then((m) => m.MyLayoutComponent),
31+
path: 'layout',
32+
loadComponent: () => import('./components/layout/my-layout.component').then((m) => m.MyLayoutComponent),
3333
},
3434
{
35-
path: "chat",
35+
path: 'chat',
3636
loadComponent: () =>
37-
import("./components/conversational-ui/conversational-ui.component").then(
37+
import('./components/conversational-ui/conversational-ui.component').then(
3838
(m) => m.ConversationalUiComponent
3939
),
4040
},
4141
{
42-
path: "editor",
43-
loadComponent: () => import("./components/editor/editor.component").then((m) => m.EditorComponent),
42+
path: 'editor',
43+
loadComponent: () => import('./components/editor/editor.component').then((m) => m.EditorComponent),
4444
},
4545
{
46-
path: "dialogs",
47-
loadComponent: () => import("./components/dialogs/dialogs.component").then((m) => m.DialogsComponent),
46+
path: 'dialogs',
47+
loadComponent: () => import('./components/dialogs/dialogs.component').then((m) => m.DialogsComponent),
4848
},
49-
{ path: "home", redirectTo: "header", pathMatch: "full" },
50-
{ path: "", redirectTo: "header", pathMatch: "full" },
49+
{
50+
path: 'treeview',
51+
loadComponent: () => import('./components/treeview/treeview.component').then((m) => m.TreeviewComponent),
52+
},
53+
{ path: 'home', redirectTo: 'header', pathMatch: 'full' },
54+
{ path: '', redirectTo: 'header', pathMatch: 'full' },
55+
{ path: 'home', redirectTo: 'header', pathMatch: 'full' },
56+
{ path: '', redirectTo: 'header', pathMatch: 'full' },
5157
];
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
11
.container {
22
display: flex;
3+
justify-content: center;
4+
height: 440px;
5+
gap: 100px;
36
width: 100%;
4-
height: 400px;
5-
flex-direction: row;
6-
margin: 0;
7-
gap: 10%;
8-
padding: 0% 5%;
7+
}
8+
9+
.wrapper {
10+
display: flex;
11+
flex-direction: column;
912
}
1013

1114
.chat {
12-
height: 400px;
13-
width: 50%;
14-
margin: 0;
15+
width: 400px;
1516
}
1617

1718
.prompt {
18-
height: 400px;
19-
width: 50%;
19+
flex-grow: 1;
20+
max-width: 400px;
21+
width: 400px;
2022
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
<div class="container">
2-
<kendo-chat class="chat" [messages]="(feed | async)!" [user]="user" (sendMessage)="sendMessage($event)">
3-
</kendo-chat>
2+
<div class="wrapper">
3+
<p>Conversational UI</p>
4+
<kendo-chat class="chat" [messages]="(feed | async)!" [user]="user" (sendMessage)="sendMessage($event)">
5+
</kendo-chat>
6+
</div>
47

5-
<kendo-aiprompt
6-
class="prompt"
7-
(promptRequest)="onPromptRequest($event)"
8-
(commandExecute)="onCommandExecute($event)"
9-
[promptOutputs]="promptOutputs"
10-
[promptCommands]="commands"
11-
[promptSuggestions]="suggestions"
12-
[(activeView)]="activeView"
13-
>
14-
<kendo-aiprompt-prompt-view></kendo-aiprompt-prompt-view>
15-
<kendo-aiprompt-output-view></kendo-aiprompt-output-view>
16-
<kendo-aiprompt-command-view></kendo-aiprompt-command-view>
17-
</kendo-aiprompt>
8+
<div class="wrapper">
9+
<p>AI Prompt</p>
10+
<kendo-aiprompt
11+
class="prompt"
12+
(promptRequest)="onPromptRequest($event)"
13+
(commandExecute)="onCommandExecute($event)"
14+
[promptOutputs]="promptOutputs"
15+
[promptCommands]="commands"
16+
[promptSuggestions]="suggestions"
17+
[(activeView)]="activeView"
18+
>
19+
<kendo-aiprompt-prompt-view></kendo-aiprompt-prompt-view>
20+
<kendo-aiprompt-output-view></kendo-aiprompt-output-view>
21+
<kendo-aiprompt-command-view></kendo-aiprompt-command-view>
22+
</kendo-aiprompt>
23+
</div>
1824
</div>

examples-standalone/kendoangular-landing-page/src/app/components/dropdowns/dropdowns.component.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import { Component } from '@angular/core';
22
import { KENDO_DROPDOWNS } from '@progress/kendo-angular-dropdowns';
33
import { employees } from '../../data/employees';
44
import { Employee } from '../../models/employee';
5-
import { dropdowntreeData } from '../../data/dropdowntree-data';
5+
import { dropdowntreeData } from '../../data/tree-data';
66
import { CommonModule } from '@angular/common';
7+
import { TreeItem } from '../../models/tree-item';
78

89
@Component({
910
selector: 'app-dropdowns',
@@ -17,7 +18,7 @@ export class DropdownsComponent {
1718
public value: any = ['Baseball', 'Cricket'];
1819
public dropdowntreeValue: { text: string; id: number } = { text: 'Sofas', id: 3 };
1920
public employees: Employee[] = employees;
20-
public furniture: any[] = dropdowntreeData;
21+
public furniture: TreeItem[] = dropdowntreeData;
2122
public expandedNodeIndices: string[] = ['Furniture'];
2223
public listItems: Array<string> = [
2324
'Baseball',
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
.container {
2+
display: flex;
3+
justify-content: center;
4+
height: 440px;
5+
gap: 100px;
6+
width: 100%;
7+
}
8+
9+
.wrapper {
10+
display: flex;
11+
flex-direction: column;
12+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<div class="container">
2+
<div class="wrapper">
3+
<p>TreeView - Multiple Selection Mode with Checkboxes</p>
4+
<kendo-treeview
5+
[nodes]="data"
6+
textField="text"
7+
kendoTreeViewHierarchyBinding
8+
childrenField="items"
9+
[filterable]="true"
10+
kendoTreeViewExpandable
11+
[expandedKeys]="expandedKeys"
12+
kendoTreeViewCheckable
13+
[(checkedKeys)]="checkedKeys"
14+
>
15+
</kendo-treeview>
16+
</div>
17+
18+
<div class="wrapper">
19+
<p>TreeView - Drag and Drop Support</p>
20+
<kendo-treeview
21+
[nodes]="treeData"
22+
textField="text"
23+
kendoTreeViewHierarchyBinding
24+
childrenField="items"
25+
kendoTreeViewExpandable
26+
expandBy="id"
27+
[expandedKeys]="[1]"
28+
kendoTreeViewDragAndDrop
29+
kendoTreeViewDragAndDropEditing
30+
>
31+
<ng-template kendoTreeViewNodeTemplate let-dataItem>
32+
<kendo-svg-icon [icon]="getIcon(dataItem)"></kendo-svg-icon>
33+
{{ dataItem.text }}
34+
</ng-template>
35+
<ng-template
36+
kendoTreeViewDragClueTemplate
37+
let-action="action"
38+
let-destinationItem="destinationItem"
39+
let-text="text"
40+
>
41+
<kendo-svg-icon [icon]="getDragStatus(action, destinationItem)"></kendo-svg-icon>
42+
<span>{{ text }}</span>
43+
</ng-template>
44+
</kendo-treeview>
45+
</div>
46+
</div>
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { Component } from '@angular/core';
2+
import { KENDO_ICONS } from '@progress/kendo-angular-icons';
3+
import {
4+
DropAction,
5+
DropPosition,
6+
KENDO_TREEVIEW,
7+
TreeItemDropEvent,
8+
TreeItemLookup,
9+
} from '@progress/kendo-angular-treeview';
10+
import {
11+
cancelIcon,
12+
codeIcon,
13+
filePdfIcon,
14+
folderIcon,
15+
imageIcon,
16+
insertBottomIcon,
17+
insertMiddleIcon,
18+
insertTopIcon,
19+
plusIcon,
20+
SVGIcon,
21+
} from '@progress/kendo-svg-icons';
22+
import { dragAndDropData, treeViewData } from '../../data/tree-data';
23+
import { TreeItem } from '../../models/tree-item';
24+
25+
const isOfType = (fileName: string, ext: string) => new RegExp(`.${ext}\$`).test(fileName);
26+
const isFile = (name: string) => name.split('.').length > 1;
27+
28+
@Component({
29+
selector: 'app-treeview',
30+
imports: [KENDO_TREEVIEW, KENDO_ICONS],
31+
templateUrl: './treeview.component.html',
32+
styleUrl: './treeview.component.css',
33+
})
34+
export class TreeviewComponent {
35+
public data: TreeItem[] = treeViewData;
36+
public treeData: TreeItem[] = dragAndDropData;
37+
public expandedKeys: any[] = ['0', '1'];
38+
public checkedKeys: any[] = ['0_1'];
39+
public plusIcon: SVGIcon = plusIcon;
40+
public insertTopIcon: SVGIcon = insertTopIcon;
41+
public insertBottomIcon: SVGIcon = insertBottomIcon;
42+
public insertMiddleIcon: SVGIcon = insertMiddleIcon;
43+
public pdfFileIcon: SVGIcon = filePdfIcon;
44+
public folderIcon: SVGIcon = folderIcon;
45+
public codeIcon: SVGIcon = codeIcon;
46+
public imageIcon: SVGIcon = imageIcon;
47+
public cancelIcon: SVGIcon = cancelIcon;
48+
49+
public getIcon({ text }: TreeItem): SVGIcon {
50+
if (isOfType(text, 'pdf')) {
51+
return this.pdfFileIcon;
52+
} else if (isOfType(text, 'html')) {
53+
return this.codeIcon;
54+
} else if (isOfType(text, 'jpg|png')) {
55+
return this.imageIcon;
56+
} else if (!isFile(text)) {
57+
return this.folderIcon;
58+
} else {
59+
return this.folderIcon;
60+
}
61+
}
62+
63+
public getDragStatus(action: DropAction, destinationItem: TreeItemLookup): SVGIcon {
64+
if (destinationItem && action === DropAction.Add && isFile(destinationItem.item.dataItem.text)) {
65+
return this.cancelIcon;
66+
}
67+
68+
switch (action) {
69+
case DropAction.Add:
70+
return this.plusIcon;
71+
case DropAction.InsertTop:
72+
return this.insertTopIcon;
73+
case DropAction.InsertBottom:
74+
return this.insertBottomIcon;
75+
case DropAction.InsertMiddle:
76+
return this.insertMiddleIcon;
77+
case DropAction.Invalid:
78+
default:
79+
return this.cancelIcon;
80+
}
81+
}
82+
83+
public handleDrop(event: TreeItemDropEvent): void {
84+
// prevent drop if attempting to add to file
85+
if (isFile(event.destinationItem.item.dataItem.text) && event.dropPosition === DropPosition.Over) {
86+
event.setValid(false);
87+
}
88+
}
89+
}

examples-standalone/kendoangular-landing-page/src/app/data/dropdowntree-data.ts

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)