Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
613 changes: 609 additions & 4 deletions playwright/cps-ui-kit/components/cps-table.spec.ts

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion playwright/fixtures/composition-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,12 @@ export const components: ComponentEntry[] = [
'Table 7',
'Table 8',
'Table 9',
'Table 10'
'Table 10',
'Table 11',
'Table 12',
'Table 13',
'Table 14',
'Table 15'
].map((tab): ComponentEntry => ({
route: '/table',
name: tab,
Expand Down
8 changes: 8 additions & 0 deletions projects/composition/src/app/api-data/cps-table.json
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,14 @@
"default": "false",
"description": "When enabled, a loader component is displayed."
},
{
"name": "loadingLabel",
"optional": false,
"readonly": false,
"type": "string",
"default": "Loading...",
"description": "Text shown alongside the loader while `loading` is true."
},
{
"name": "tableStyle",
"optional": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
[htmlCode]="examples.table1.html"
[tsCode]="examples.table1.ts">
<cps-table
data-testid="table-1-paginated-filters"
[data]="data"
[paginator]="true"
sortMode="multiple"
Expand Down Expand Up @@ -58,6 +59,7 @@
[tsCode]="examples.table2.ts">
@if (selectedTabIndex === 1) {
<cps-table
data-testid="table-2-virtual-default-render"
[showGlobalFilter]="true"
[data]="dataVirtual"
[columns]="colsVirtual"
Expand All @@ -77,6 +79,7 @@
[htmlCode]="examples.table3.html"
[tsCode]="examples.table3.ts">
<cps-table
data-testid="table-3-reorder-menu"
[data]="data"
[reorderableRows]="true"
[showActionBtn]="true"
Expand Down Expand Up @@ -127,6 +130,7 @@
[htmlCode]="examples.table4.html"
[tsCode]="examples.table4.ts">
<cps-table
data-testid="table-4-select-expand"
[data]="data"
dataKey="a"
[columns]="colsWithFilterType"
Expand Down Expand Up @@ -200,6 +204,7 @@
[htmlCode]="examples.table5.html"
[tsCode]="examples.table5.ts">
<cps-table
data-testid="table-5-nested-header"
[data]="data"
[selectable]="true"
toolbarSize="small"
Expand Down Expand Up @@ -252,6 +257,7 @@
[htmlCode]="examples.table6.html"
[tsCode]="examples.table6.ts">
<cps-table
data-testid="table-6-export"
[data]="data"
[columns]="cols"
[rowHover]="false"
Expand Down Expand Up @@ -336,8 +342,10 @@
<cps-tab label="Table 8">
<app-code-example [htmlCode]="examples.table8.html">
<cps-table
data-testid="table-8-empty"
[data]="[]"
toolbarTitle="Empty table"
[hasToolbar]="false"
emptyMessage="No records match your criteria"
emptyBodyHeight="22rem">
<ng-template #header>
<th cpsTColSortable="a">A</th>
Expand All @@ -354,6 +362,7 @@
[htmlCode]="examples.table9.html"
[tsCode]="examples.table9.ts">
<cps-table
data-testid="table-9-loading"
[data]="data"
[loading]="true"
scrollHeight="25rem"
Expand All @@ -367,6 +376,7 @@
[htmlCode]="examples.table10.html"
[tsCode]="examples.table10.ts">
<cps-table
data-testid="table-10-html"
[data]="dataWithHTML"
scrollHeight="22rem"
[columns]="colsHTML"
Expand All @@ -380,5 +390,95 @@
</cps-table>
</app-code-example>
</cps-tab>
<cps-tab label="Table 11">
<app-code-example
[htmlCode]="examples.table11.html"
[tsCode]="examples.table11.ts">
<cps-table
data-testid="table-11-lazy"
[data]="lazyData"
[columns]="cols"
[lazy]="true"
[lazyLoadOnInit]="true"
[loading]="lazyLoading"
loadingLabel="Fetching..."
[paginator]="true"
[rows]="lazyRows"
[totalRecords]="lazyTotalRecords"
(lazyLoaded)="onLazyLoad($event)"
toolbarTitle="Table with lazy/server-side loading, driven by a simulated 600ms fetch delay">
</cps-table>
</app-code-example>
</cps-tab>
<cps-tab label="Table 12">
<app-code-example
[htmlCode]="examples.table12.html"
[tsCode]="examples.table12.ts">
<cps-table
data-testid="table-12-always-show-paginator-false"
[data]="manyRecordsForPaginator ? data : data.slice(0, 3)"
[columns]="cols"
[paginator]="true"
[rows]="10"
[alwaysShowPaginator]="false"
toolbarTitle="Table whose paginator hides when everything fits on one page">
</cps-table>
<cps-switch
class="spaced-from-table"
[(ngModel)]="manyRecordsForPaginator"
label="Load enough records for multiple pages">
</cps-switch>
</app-code-example>
</cps-tab>
<cps-tab label="Table 13">
<app-code-example
[htmlCode]="examples.table13.html"
[tsCode]="examples.table13.ts">
<cps-table
data-testid="table-13-additional-btn-on-select"
[data]="data"
[columns]="cols"
[selectable]="true"
[showAdditionalBtnOnSelect]="true"
additionalBtnOnSelectTitle="Archive"
additionalBtnOnSelectIcon="star"
(additionalBtnOnSelectClicked)="
onAdditionalBtnOnSelectClicked($event)
"
toolbarTitle="Selectable table with an additional toolbar action shown alongside Remove when rows are selected">
</cps-table>
</app-code-example>
</cps-tab>
<cps-tab label="Table 14">
<app-code-example
[htmlCode]="examples.table14.html"
[tsCode]="examples.table14.ts">
<cps-table
data-testid="table-14-custom-sort"
[data]="customSortData"
[columns]="customSortCols"
[sortable]="true"
[customSort]="true"
(customSortFunction)="onCustomSort($event)"
toolbarTitle="Table with a custom sort function (sorts by string length instead of alphabetically)">
</cps-table>
</app-code-example>
</cps-tab>
<cps-tab label="Table 15">
<app-code-example
[htmlCode]="examples.table15.html"
[tsCode]="examples.table15.ts">
<cps-table
data-testid="table-15-initial-columns"
[data]="dataVirtual"
[columns]="colsVirtual"
[initialColumns]="colsVirtual.slice(0, 3)"
[virtualScroll]="true"
scrollHeight="26rem"
[showColumnsToggleBtn]="true"
toolbarTitle="Table that initially shows only a subset of columns. Use the columns button to reveal the rest">
</cps-table>
</app-code-example>
</cps-tab>
</cps-tab-group>
</app-component-docs-viewer>
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
color: red;
}

.spaced-from-table {
margin-top: 1rem;
}

::ng-deep {
.table-page--sub-tabs {
padding-top: 0.625rem;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, inject } from '@angular/core';
import { FormsModule } from '@angular/forms';
import {
CpsTableComponent,
Expand All @@ -14,7 +14,9 @@ import {
CpsTabChangeEvent,
CpsColumnFilterMatchMode,
CpsMenuItem,
CpsIconComponent
CpsIconComponent,
CpsSwitchComponent,
CpsNotificationService
} from 'cps-ui-kit';
import { ComponentDocsViewerComponent } from '../../components/component-docs-viewer/component-docs-viewer.component';
import { CodeExampleComponent } from '../../components/code-example/code-example.component';
Expand All @@ -39,6 +41,7 @@ import { DatePipe, PercentPipe, UpperCasePipe } from '@angular/common';
CpsTabComponent,
CpsButtonToggleComponent,
CpsIconComponent,
CpsSwitchComponent,
ComponentDocsViewerComponent,
CodeExampleComponent
],
Expand All @@ -47,6 +50,8 @@ import { DatePipe, PercentPipe, UpperCasePipe } from '@angular/common';
host: { class: 'composition-page' }
})
export class TablePageComponent implements OnInit {
private readonly _notifService = inject(CpsNotificationService);

readonly examples = tableExamples;

selectedTabIndex = 0;
Expand Down Expand Up @@ -358,6 +363,19 @@ export class TablePageComponent implements OnInit {

selCols: { [key: string]: any }[] = [];

customSortData = [
{ name: 'Andrei', city: 'Tyumen' },
{ name: 'Oleksandra', city: 'Kharkiv' },
{ name: 'Lukas', city: 'Kosice' },
{ name: 'Terrance', city: 'Johannesburg' },
{ name: 'Michael', city: 'Nairobi' }
];

customSortCols = [
{ field: 'name', header: 'Name' },
{ field: 'city', header: 'City' }
];

dataVirtual: {
a: string;
b: string;
Expand All @@ -383,6 +401,16 @@ export class TablePageComponent implements OnInit {

colsHTML = this.colsVirtual.slice(0, 3);

lazyData: any[] = [];
lazyTotalRecords = 0;
lazyLoading = false;
lazyRows = 10;
private _lazyLoadTimeout?: ReturnType<typeof setTimeout>;
private _lastLazyFirst = -1;
private _lastLazyRows = -1;

manyRecordsForPaginator = false;

componentData = ComponentData;

customRowMenuItems: CpsMenuItem[] = [
Expand Down Expand Up @@ -430,19 +458,21 @@ export class TablePageComponent implements OnInit {
onActionBtnClicked() {
this.isRemoveBtnVisible = !this.isRemoveBtnVisible;
const visibilityStatus = this.isRemoveBtnVisible ? 'visible' : 'hidden';
alert(`'Remove' buttons are now ${visibilityStatus}`);
this._notifService.info(`'Remove' buttons are now ${visibilityStatus}`);
}

onRowsToRemove(rows: any[]) {
this.data = this.data.filter((r) => !rows.includes(r));
}

onReloadBtnClicked() {
alert('Data reload button clicked');
this._notifService.info('Data reload button clicked');
}

onEditRowButtonClicked(item: any) {
alert(`Edit row button clicked. Item: ${JSON.stringify(item)}`);
this._notifService.info(
`Edit row button clicked. Item: ${JSON.stringify(item)}`
);
}

onRowsSelectionChanged(rows: any) {
Expand All @@ -456,4 +486,38 @@ export class TablePageComponent implements OnInit {
changeTab({ newIndex }: CpsTabChangeEvent) {
this.selectedTabIndex = newIndex;
}

onLazyLoad(event: { first?: number; rows?: number }) {
const first = event.first ?? 0;
const rows = event.rows ?? this.lazyRows;

if (first === this._lastLazyFirst && rows === this._lastLazyRows) return;
this._lastLazyFirst = first;
this._lastLazyRows = rows;

Promise.resolve().then(() => {
this.lazyLoading = true;
clearTimeout(this._lazyLoadTimeout);
this._lazyLoadTimeout = setTimeout(() => {
this.lazyTotalRecords = this.dataVirtual.length;
this.lazyData = this.dataVirtual.slice(first, first + rows);
this.lazyLoading = false;
}, 600);
});
}

onAdditionalBtnOnSelectClicked(rows: any[]) {
this._notifService.success(`Archive clicked for ${rows.length} row(s)`);
}
Comment on lines +507 to +511

onCustomSort(event: { data: any[]; field?: string; order?: number }) {
const { data, field, order } = event;
if (!field) return;
data.sort((a, b) => {
const v1 = String(a[field] ?? '');
const v2 = String(b[field] ?? '');
const result = v1.length - v2.length || v1.localeCompare(v2);
return (order ?? 1) * result;
});
}
}
Loading
Loading