mirror of
https://github.com/akveo/ngx-admin.git
synced 2025-12-16 23:40:14 +01:00
feat: add tree grid example
This commit is contained in:
parent
2144c7a3d9
commit
1e64e6b6e3
6 changed files with 201 additions and 5 deletions
|
|
@ -206,6 +206,10 @@ export const MENU_ITEMS: NbMenuItem[] = [
|
|||
title: 'Smart Table',
|
||||
link: '/pages/tables/smart-table',
|
||||
},
|
||||
{
|
||||
title: 'Tree Grid',
|
||||
link: '/pages/tables/tree-grid',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3,14 +3,21 @@ import { Routes, RouterModule } from '@angular/router';
|
|||
|
||||
import { TablesComponent } from './tables.component';
|
||||
import { SmartTableComponent } from './smart-table/smart-table.component';
|
||||
import { TreeGridComponent } from './tree-grid/tree-grid.component';
|
||||
|
||||
const routes: Routes = [{
|
||||
path: '',
|
||||
component: TablesComponent,
|
||||
children: [{
|
||||
path: 'smart-table',
|
||||
component: SmartTableComponent,
|
||||
}],
|
||||
children: [
|
||||
{
|
||||
path: 'smart-table',
|
||||
component: SmartTableComponent,
|
||||
},
|
||||
{
|
||||
path: 'tree-grid',
|
||||
component: TreeGridComponent,
|
||||
},
|
||||
],
|
||||
}];
|
||||
|
||||
@NgModule({
|
||||
|
|
@ -22,4 +29,5 @@ export class TablesRoutingModule { }
|
|||
export const routedComponents = [
|
||||
TablesComponent,
|
||||
SmartTableComponent,
|
||||
TreeGridComponent,
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,19 +1,24 @@
|
|||
import { NgModule } from '@angular/core';
|
||||
import { NbCardModule } from '@nebular/theme';
|
||||
import { NbCardModule, NbIconModule, NbInputModule, NbTreeGridModule } from '@nebular/theme';
|
||||
import { Ng2SmartTableModule } from 'ng2-smart-table';
|
||||
|
||||
import { ThemeModule } from '../../@theme/theme.module';
|
||||
import { TablesRoutingModule, routedComponents } from './tables-routing.module';
|
||||
import { FsIconComponent } from './tree-grid/tree-grid.component';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
NbCardModule,
|
||||
NbTreeGridModule,
|
||||
NbIconModule,
|
||||
NbInputModule,
|
||||
ThemeModule,
|
||||
TablesRoutingModule,
|
||||
Ng2SmartTableModule,
|
||||
],
|
||||
declarations: [
|
||||
...routedComponents,
|
||||
FsIconComponent,
|
||||
],
|
||||
})
|
||||
export class TablesModule { }
|
||||
|
|
|
|||
34
src/app/pages/tables/tree-grid/tree-grid.component.html
Normal file
34
src/app/pages/tables/tree-grid/tree-grid.component.html
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<nb-card>
|
||||
<nb-card-body>
|
||||
|
||||
<label class="search-label" for="search">Search:</label>
|
||||
<input nbInput [nbFilterInput]="dataSource" id="search" class="search-input">
|
||||
|
||||
<table [nbTreeGrid]="dataSource" [nbSort]="dataSource" (sort)="updateSort($event)">
|
||||
|
||||
<tr nbTreeGridHeaderRow *nbTreeGridHeaderRowDef="allColumns"></tr>
|
||||
<tr nbTreeGridRow *nbTreeGridRowDef="let row; columns: allColumns"></tr>
|
||||
|
||||
<ng-container [nbTreeGridColumnDef]="customColumn">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(customColumn)" *nbTreeGridHeaderCellDef>
|
||||
{{customColumn}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">
|
||||
<ngx-fs-icon [kind]="row.data.kind" [expanded]="row.expanded"></ngx-fs-icon>
|
||||
{{row.data[customColumn]}}
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngFor="let column of defaultColumns; let index = index"
|
||||
[nbTreeGridColumnDef]="column"
|
||||
[showOn]="getShowOn(index)">
|
||||
<th nbTreeGridHeaderCell [nbSortHeader]="getSortDirection(column)" *nbTreeGridHeaderCellDef>
|
||||
{{column}}
|
||||
</th>
|
||||
<td nbTreeGridCell *nbTreeGridCellDef="let row">{{row.data[column] || '-'}}</td>
|
||||
</ng-container>
|
||||
|
||||
</table>
|
||||
|
||||
</nb-card-body>
|
||||
</nb-card>
|
||||
47
src/app/pages/tables/tree-grid/tree-grid.component.scss
Normal file
47
src/app/pages/tables/tree-grid/tree-grid.component.scss
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
button[nbTreeGridRowToggle] {
|
||||
background: transparent;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.search-label {
|
||||
display: block;
|
||||
}
|
||||
.search-input {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.nb-column-name {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.nb-tree-grid-header-cell,
|
||||
.nb-tree-grid-header-cell button {
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 400px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 500px) {
|
||||
.nb-column-name,
|
||||
.nb-column-size,
|
||||
.nb-column-kind {
|
||||
width: 33.333%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 600px) {
|
||||
.nb-column-name {
|
||||
width: 31%;
|
||||
}
|
||||
.nb-column-size,
|
||||
.nb-column-kind,
|
||||
.nb-column-items {
|
||||
width: 23%;
|
||||
}
|
||||
}
|
||||
98
src/app/pages/tables/tree-grid/tree-grid.component.ts
Normal file
98
src/app/pages/tables/tree-grid/tree-grid.component.ts
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import { Component, Input } from '@angular/core';
|
||||
import { NbSortDirection, NbSortRequest, NbTreeGridDataSource, NbTreeGridDataSourceBuilder } from '@nebular/theme';
|
||||
|
||||
interface TreeNode<T> {
|
||||
data: T;
|
||||
children?: TreeNode<T>[];
|
||||
expanded?: boolean;
|
||||
}
|
||||
|
||||
interface FSEntry {
|
||||
name: string;
|
||||
size: string;
|
||||
kind: string;
|
||||
items?: number;
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-tree-grid',
|
||||
templateUrl: './tree-grid.component.html',
|
||||
styleUrls: ['./tree-grid.component.scss'],
|
||||
})
|
||||
export class TreeGridComponent {
|
||||
customColumn = 'name';
|
||||
defaultColumns = [ 'size', 'kind', 'items' ];
|
||||
allColumns = [ this.customColumn, ...this.defaultColumns ];
|
||||
|
||||
dataSource: NbTreeGridDataSource<FSEntry>;
|
||||
|
||||
sortColumn: string;
|
||||
sortDirection: NbSortDirection = NbSortDirection.NONE;
|
||||
|
||||
constructor(private dataSourceBuilder: NbTreeGridDataSourceBuilder<FSEntry>) {
|
||||
this.dataSource = this.dataSourceBuilder.create(this.data);
|
||||
}
|
||||
|
||||
updateSort(sortRequest: NbSortRequest): void {
|
||||
this.sortColumn = sortRequest.column;
|
||||
this.sortDirection = sortRequest.direction;
|
||||
}
|
||||
|
||||
getSortDirection(column: string): NbSortDirection {
|
||||
if (this.sortColumn === column) {
|
||||
return this.sortDirection;
|
||||
}
|
||||
return NbSortDirection.NONE;
|
||||
}
|
||||
|
||||
private data: TreeNode<FSEntry>[] = [
|
||||
{
|
||||
data: { name: 'Projects', size: '1.8 MB', items: 5, kind: 'dir' },
|
||||
children: [
|
||||
{ data: { name: 'project-1.doc', kind: 'doc', size: '240 KB' } },
|
||||
{ data: { name: 'project-2.doc', kind: 'doc', size: '290 KB' } },
|
||||
{ data: { name: 'project-3', kind: 'txt', size: '466 KB' } },
|
||||
{ data: { name: 'project-4.docx', kind: 'docx', size: '900 KB' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
data: { name: 'Reports', kind: 'dir', size: '400 KB', items: 2 },
|
||||
children: [
|
||||
{ data: { name: 'Report 1', kind: 'doc', size: '100 KB' } },
|
||||
{ data: { name: 'Report 2', kind: 'doc', size: '300 KB' } },
|
||||
],
|
||||
},
|
||||
{
|
||||
data: { name: 'Other', kind: 'dir', size: '109 MB', items: 2 },
|
||||
children: [
|
||||
{ data: { name: 'backup.bkp', kind: 'bkp', size: '107 MB' } },
|
||||
{ data: { name: 'secret-note.txt', kind: 'txt', size: '2 MB' } },
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
getShowOn(index: number) {
|
||||
const minWithForMultipleColumns = 400;
|
||||
const nextColumnStep = 100;
|
||||
return minWithForMultipleColumns + (nextColumnStep * index);
|
||||
}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ngx-fs-icon',
|
||||
template: `
|
||||
<nb-tree-grid-row-toggle [expanded]="expanded" *ngIf="isDir(); else fileIcon">
|
||||
</nb-tree-grid-row-toggle>
|
||||
<ng-template #fileIcon>
|
||||
<nb-icon icon="file-text-outline"></nb-icon>
|
||||
</ng-template>
|
||||
`,
|
||||
})
|
||||
export class FsIconComponent {
|
||||
@Input() kind: string;
|
||||
@Input() expanded: boolean;
|
||||
|
||||
isDir(): boolean {
|
||||
return this.kind === 'dir';
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue