Skip to content
This repository was archived by the owner on Feb 4, 2025. It is now read-only.

Commit 7dfeaca

Browse files
Merge pull request #122 from ssuperczynski/loading-spinner
Loading spinner
2 parents e9666b3 + 8e1690c commit 7dfeaca

16 files changed

+103
-39
lines changed

.travis.yml

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ language: node_js
22
node_js:
33
- "8"
44
script:
5+
- npm run lint
56
- npm run e2e
7+
- npm run build:lib
68
before_install:
79
- export DISPLAY=:99.0
810
- sh -e /etc/init.d/xvfb start
911
before_script:
10-
- npm install && npm run build:lib
12+
- npm install
1113
notifications:
1214
webhooks: https://www.travisbuddy.com/
1315
email: false

e2e/app.po.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,14 @@ export class AppPage {
4545
async searchByName(name: string) {
4646
return await element
4747
.all(by.css('input[type=text]'))
48-
.get(4)
48+
.get(5)
49+
.sendKeys(name);
50+
}
51+
52+
async searchByAddress(name: string) {
53+
return await element
54+
.all(by.css('input[type=text]'))
55+
.get(3)
4956
.sendKeys(name);
5057
}
5158

e2e/pagination.e2e-spec.ts

+14-10
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,32 @@ describe('table pagination', () => {
1212
const table = await data.getText();
1313
expect(table.length).toEqual(10);
1414
const row = await data.get(0).getText();
15-
expect(row).toEqual('+1 (882) 527-2652\n' +
16-
'25\n' +
17-
'GYNKO\n' +
18-
'Gordon Rutledge\n' +
19-
'false');
15+
expect(row).toEqual('+1 (949) 527-2108\n' +
16+
'36\n' +
17+
'Some street\n' +
18+
'KONGENE\n' +
19+
'Deanne Contreras\n' +
20+
'true');
2021
});
2122
it('should pagination NEXT button show next 10 elements', async () => {
2223
await page.clickPaginationNext();
2324
const row = await data.get(0).getText();
2425
expect(row).toEqual('+1 (902) 500-3665\n' +
2526
'28\n' +
27+
'Southeast street\n' +
2628
'CALCULA\n' +
2729
'Wilson Hatfield\n' +
2830
'true');
2931
});
3032
it('should pagination PREV button show previous 10 elements', async () => {
3133
await page.clickPaginationPrev();
3234
const row = await data.get(0).getText();
33-
expect(row).toEqual('+1 (882) 527-2652\n' +
34-
'25\n' +
35-
'GYNKO\n' +
36-
'Gordon Rutledge\n' +
37-
'false');
35+
expect(row).toEqual('+1 (949) 527-2108\n' +
36+
'36\n' +
37+
'Some street\n' +
38+
'KONGENE\n' +
39+
'Deanne Contreras\n' +
40+
'true');
3841
});
3942
it('should display 10 rows from 2 page, when pagination "2" clicked', async () => {
4043
await page.clickPagination2nd();
@@ -43,6 +46,7 @@ describe('table pagination', () => {
4346
const row = await data.get(0).getText();
4447
expect(row).toEqual('+1 (902) 500-3665\n' +
4548
'28\n' +
49+
'Southeast street\n' +
4650
'CALCULA\n' +
4751
'Wilson Hatfield\n' +
4852
'true');

e2e/search.e2e-spec.ts

+14-2
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,29 @@ describe('table search', () => {
1313
const row = await data.getText();
1414
expect(row).toEqual('+1 (949) 527-2108\n' +
1515
'36\n' +
16+
'Some street\n' +
1617
'KONGENE\n' +
1718
'Deanne Contreras\n' +
18-
'false');
19+
'true');
1920
});
2021
it('should find 1 row when filtering by name', async () => {
2122
await page.searchByName('Scott Barker');
2223
const row = await data.getText();
2324
expect(row).toEqual('+1 (939) 530-3189\n' +
2425
'34\n' +
26+
'Dacota street\n' +
2527
'MARKETOID\n' +
2628
'Scott Barker\n' +
27-
'false');
29+
'true');
30+
});
31+
it('should find 1 row when filtering by address street which is nested object property', async () => {
32+
await page.searchByAddress('Dacota');
33+
const row = await data.getText();
34+
expect(row).toEqual('+1 (939) 530-3189\n' +
35+
'34\n' +
36+
'Dacota street\n' +
37+
'MARKETOID\n' +
38+
'Scott Barker\n' +
39+
'true');
2840
});
2941
});

package-lock.json

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ngx-easy-table",
3-
"version": "3.1.0",
3+
"version": "3.2.0",
44
"description": "Angular easy table",
55
"typings": "index.ts",
66
"repository": "https://github.com/ssuperczynski/ngx-easy-table.git",

src/app/app.component.ts

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Component, OnInit } from '@angular/core';
22
import { ConfigService } from './app.service';
33
import { data } from '../assets/data';
4+
import { Columns } from './ngx-easy-table/model/columns';
45

56
@Component({
67
selector: 'app-table',
@@ -11,20 +12,20 @@ import { data } from '../assets/data';
1112
export class AppComponent implements OnInit {
1213
configuration;
1314
data;
14-
columns;
15+
columns: Columns[];
1516

1617
constructor() {
1718
}
1819

1920
ngOnInit() {
2021
this.configuration = ConfigService.config;
2122
this.columns = [
22-
{ key: 'phone', title: 'phone' },
23-
{ key: 'age', title: 'age' },
24-
{ key: 'address.street', title: 'Address' },
25-
{ key: 'company', title: 'company' },
26-
{ key: 'name', title: 'name' },
27-
{ key: 'isActive', title: 'isActive' },
23+
{ key: 'phone', title: 'phone', placeholder: 'Search phone', width: '15%' },
24+
{ key: 'age', title: 'age', placeholder: 'Search age', width: '10%' },
25+
{ key: 'address.street', title: 'Address', placeholder: 'Search street', width: '25%' },
26+
{ key: 'company', title: 'company', placeholder: 'Search company', width: '20%' },
27+
{ key: 'name', title: 'name', placeholder: 'Search name', width: '20%' },
28+
{ key: 'isActive', title: 'isActive', placeholder: 'Search status', width: '10%' },
2829
];
2930
this.data = data;
3031
}

src/app/app.service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ export class ConfigService {
2424
collapseAllRows: false,
2525
checkboxes: false,
2626
resizeColumn: false,
27+
fixedColumnWidth: false,
2728
};
2829
}

src/app/ngx-easy-table/components/base/base.component.css

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
* {
22
font-family: Verdana, serif;
33
}
4-
54
.ngx-table__table-row--selected {
65
background: #9cbff9 !important;
76
}
8-
97
.ngx-table__table-col--selected {
108
background: #9cbff9 !important;
119
}
12-
1310
.ngx-table__table-cell--selected {
1411
background: #9cbff9 !important;
1512
}
1613
.ngx-table__table-no-results {
1714
text-align: center;
1815
}
16+
.ngx-table__table-loader-wrapper {
17+
display: flex;
18+
justify-content: center;
19+
align-items: center;
20+
}
1921
.ngx-table__table-loader {
2022
border: 4px solid #f3f3f3;
2123
border-top: 4px solid #3498db;
@@ -26,11 +28,9 @@
2628
margin-right: auto;
2729
animation: spin 1s linear infinite;
2830
}
29-
3031
.ngx-table__header-cell {
3132
position: relative;
3233
}
33-
3434
.ngx-table__column-resizer {
3535
background-color: #f3f3f3;
3636
cursor: col-resize;
@@ -43,7 +43,6 @@
4343
top: 0;
4444
width: 3px;
4545
}
46-
4746
@keyframes spin {
4847
0% { transform: rotate(0deg); }
4948
100% { transform: rotate(360deg); }

src/app/ngx-easy-table/components/base/base.component.html

+10-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
</div>
1010
</div>
1111
<div class="ngx-columns">
12-
<table class="ngx-table ngx-table-striped ngx-table-hover">
12+
<table id="table" class="ngx-table ngx-table-striped ngx-table-hover">
1313
<thead>
1414
<tr class="ngx-table__header" *ngIf="config.headerEnabled">
1515
<th *ngIf="config.checkboxes">
@@ -21,7 +21,9 @@
2121
</div>
2222
</th>
2323
<ng-container *ngFor="let column of columns">
24-
<th class="ngx-table__header-cell" #th
24+
<th class="ngx-table__header-cell"
25+
#th
26+
[attr.width]="getColumnWidth(column)"
2527
(mousedown)="onMouseDown($event, th)"
2628
(mouseup)="onMouseUp($event)"
2729
(mousemove)="onMouseMove($event)">
@@ -68,7 +70,7 @@
6870
<th *ngIf="config.additionalActions || config.detailsTemplate"></th>
6971
</tr>
7072
</thead>
71-
<tbody *ngIf="data && !config.isLoading">
73+
<tbody *ngIf="data && !isLoading">
7274
<ng-container *ngIf="rowTemplate">
7375
<ng-container *ngFor="let row of data | sort:sortBy | search:term | global:globalSearchTerm | paginate: { itemsPerPage: limit, currentPage: page, totalItems: count, id: id };
7476
let rowIndex = index">
@@ -177,10 +179,13 @@
177179
</td>
178180
</tr>
179181
</tbody>
180-
<tbody *ngIf="config.isLoading">
182+
<tbody *ngIf="isLoading">
181183
<tr class="ngx-table__body-loading">
182184
<td [attr.colspan]="columns.length + 1">
183-
<div class="ngx-table__table-loader"></div>
185+
<div [style.height]="loadingHeight"
186+
class="ngx-table__table-loader-wrapper">
187+
<div class="ngx-table__table-loader"></div>
188+
</div>
184189
</td>
185190
</tr>
186191
</tbody>

src/app/ngx-easy-table/components/base/base.component.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { Config } from '../../model/config';
2121
import { flatMap, groupBy, reduce } from 'rxjs/operators';
2222
import { from } from 'rxjs';
2323
import { FiltersService } from '../../services/filters.service';
24+
import { Columns } from '../../model/columns';
2425

2526
@Component({
2627
selector: 'ngx-table',
@@ -49,12 +50,13 @@ export class BaseComponent implements OnInit, OnChanges, AfterViewInit {
4950
id;
5051
th = undefined;
5152
startOffset;
53+
loadingHeight = '30px';
5254
@Input() configuration: Config;
5355
@Input() data: Array<Object>;
5456
@Input() pagination;
5557
@Input() groupRowsBy;
5658
@Input() detailsTemplate;
57-
@Input() columns: Array<string>;
59+
@Input() columns: Columns[];
5860
@Output() event = new EventEmitter();
5961
@ContentChild(TemplateRef) public rowTemplate: TemplateRef<any>;
6062

@@ -251,4 +253,27 @@ export class BaseComponent implements OnInit, OnChanges, AfterViewInit {
251253

252254
return FiltersService.getPath(split, row);
253255
}
256+
257+
get isLoading(): boolean {
258+
const rows = document.getElementById('table')['rows'];
259+
if (rows.length > 3) {
260+
this.getLoadingHeight(rows);
261+
}
262+
return this.config.isLoading;
263+
}
264+
265+
getLoadingHeight(rows: any): void {
266+
const searchEnabled = this.configuration.searchEnabled ? 1 : 0;
267+
const headerEnabled = this.configuration.headerEnabled ? 1 : 0;
268+
const borderTrHeight = 1;
269+
const borderDivHeight = 2;
270+
this.loadingHeight = (rows.length - searchEnabled - headerEnabled) * (rows[3].offsetHeight - borderTrHeight) - borderDivHeight + 'px';
271+
}
272+
273+
getColumnWidth(column: any): string {
274+
if (column.width) {
275+
return column.width;
276+
}
277+
return this.config.fixedColumnWidth ? 100 / this.columns.length + '%' : null;
278+
}
254279
}

src/app/ngx-easy-table/components/header/header.component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import { Component, Input, Output, EventEmitter } from '@angular/core';
77
<input type="text"
88
id="search_{{ column['key'] }}"
99
aria-label="Search"
10-
placeholder="Search {{ column['title'] }}"
10+
placeholder="{{ column['placeholder'] ? column['placeholder'] : column['title'] }}"
1111
class="ngx-table__header-search ngx-form-input ngx-input-sm"
1212
#input
1313
(input)="update.emit({value: input.value, key: column['key']})"
1414
>
15-
</label>`
15+
</label>`,
1616
})
1717

1818
export class HeaderComponent {
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
export interface Columns {
2+
key: string;
3+
title: string;
4+
placeholder: string;
5+
width: string;
6+
}

src/app/ngx-easy-table/model/config.ts

+1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export interface Config {
1919
collapseAllRows: boolean;
2020
checkboxes: boolean;
2121
resizeColumn: boolean;
22+
fixedColumnWidth: boolean;
2223
}

src/app/ngx-easy-table/services/config-service.ts

+1
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ export class ConfigService {
2424
collapseAllRows: false,
2525
checkboxes: true,
2626
resizeColumn: true,
27+
fixedColumnWidth: false,
2728
};
2829
}

src/assets/data.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export const data = [
55
address: { street: 'Some street', number: 12 },
66
company: 'KONGENE',
77
name: 'Deanne Contreras',
8-
isActive: false,
8+
isActive: true,
99
}, {
1010
phone: '+1 (878) 515-3653',
1111
age: 32,
@@ -89,7 +89,7 @@ export const data = [
8989
address: { street: 'Dacota street', number: 12 },
9090
company: 'MARKETOID',
9191
name: 'Scott Barker',
92-
isActive: false,
92+
isActive: true,
9393
}, {
9494
phone: '+1 (949) 600-2827',
9595
age: 29,

0 commit comments

Comments
 (0)