Skip to content

Commit f395389

Browse files
authored
Merge pull request #24 from kreuzerk/feature/orderChange
feat(sort): emit previous and current change on sort event
2 parents 25977f0 + 0d6a078 commit f395389

File tree

9 files changed

+94
-38
lines changed

9 files changed

+94
-38
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414
- [Download the module](#download-the-module)
1515
- [Apply the directive](#apply-the-directive)
1616
- [React on changes](#react-on-changes)
17+
- [API](#api)
18+
- [Inputs](#inputs)
19+
- [Outputs](#outputs)
1720

1821
# Getting started
1922
## Download the module
@@ -45,7 +48,7 @@ In most cases you are interested in the new sort order. Often you want to store
4548
Pass your items to the directive via the ngSortGridItems input.
4649

4750
![Grid demo](https://raw.githubusercontent.com/kreuzerk/ng-sortgrid/master/projects/ng-sortgrid-demo/src/assets/gs3.png)
48-
React on the 'sorted' output events
51+
React on the 'sorted' output event. The `sorted` output event emits a `NgsgOrderChange` which contains the `previousOrder` and the `currentOrder`
4952

5053
![Grid demo](https://raw.githubusercontent.com/kreuzerk/ng-sortgrid/master/projects/ng-sortgrid-demo/src/assets/gs4.png)
5154

@@ -98,3 +101,20 @@ at the top of your page. In this case you need to scroll once you drag an elemen
98101
The *scrollSpeed* property accepts a number and allows you to specify the scrolling speed.
99102

100103
[Check out the scroll demo](https://kreuzerk.github.io/ng-sortgrid/scrolling)
104+
105+
# API
106+
107+
## Inputs
108+
| Value | Description | Default|
109+
|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------|--------|
110+
| ngSortGridGroup: string | Groups a grid - avoids that items from one grid can be dragged to another grid |undefined|
111+
| ngSortGridItems: any[] | Sort grid items. Pass down a list of all your items. This list is needed to enable the sorting feature.|undefined|
112+
| autoScroll: boolean | Flag to enable autoscrolling|false|
113+
| scrollPointTop: number | Custom top scrollpoint in pixels|if autoscroll is applied we start scrolling if we pass the top border|
114+
| scrollPointBottom: number | Custom bottom scrollpoint in pixels|if autoscroll is applied we start scrolling if we pass the bottom border|
115+
| scrollSpeed: number | Scrollspeed, the higher the value, the higher we scroll.|50 - only applies if autoscrolling is on|
116+
117+
## Outputs
118+
| Value | Description | Default|
119+
|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------|--------|
120+
| sorted: EventEmitter<NgsgOrderChange<T> | Emits an event after we sorted the items, each event is of type NgsgOrderChange. The NgsgOrderChange contains the previousOrder and the currentOrder |undefined|

projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
<h5 style="margin-bottom: 20px">4. Load items and use them with the async pipe</h5>
22
<button style="margin-bottom: 20px" class="btn btn-primary" (click)="loadItems()">Load items</button>
33
<div class="card border-primary mb-3">
4+
<div class="card-body" *ngIf="previousSortOrder.length > 0">
5+
<h1 class="card-title">Previous sort order</h1>
6+
<h2 class="card-text">{{ previousSortOrder }}</h2>
7+
</div>
48
<div class="card-body">
5-
<h1 class="card-title">Sort order</h1>
6-
<h2 class="card-text">{{ sortOrder }}</h2>
9+
<h1 class="card-title">Current sort order</h1>
10+
<h2 class="card-text">{{ currentSortOrder }}</h2>
711
</div>
812
</div>
913
<div class="example-container">
Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
1-
import {Component} from '@angular/core';
1+
import {Component, OnInit} from '@angular/core';
22
import {Observable, of} from 'rxjs';
33
import {delay, tap} from 'rxjs/operators';
44

5+
import {NgsgOrderChange} from '../../../../../../ng-sortgrid/src/lib/shared/ngsg-order-change.model';
6+
57
@Component({
68
selector: 'ngsg-demo-async',
79
templateUrl: './async-pipe-memory.component.html',
810
styleUrls: ['./async-pipe-memory.component.css']
911
})
10-
export class AsyncPipeMemoryComponent {
12+
export class AsyncPipeMemoryComponent implements OnInit {
1113

1214
item$: Observable<number[]>;
1315
loading = false;
14-
public sortOrder: number[];
16+
public currentSortOrder: number[];
17+
public previousSortOrder: number[];
18+
19+
ngOnInit(): void {
20+
this.previousSortOrder = [];
21+
this.currentSortOrder = [];
22+
}
1523

1624
public loadItems(): void {
1725
this.loading = true;
@@ -21,8 +29,8 @@ export class AsyncPipeMemoryComponent {
2129
);
2230
}
2331

24-
public applyOrder(newOrder: number[]): void {
25-
this.sortOrder = newOrder;
32+
public applyOrder(orderChange: NgsgOrderChange<number>): void {
33+
this.currentSortOrder = orderChange.currentOrder;
34+
this.previousSortOrder = orderChange.previousOrder;
2635
}
27-
2836
}
Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
<div class="card border-primary mb-3">
2+
<div class="card-body" *ngIf="previousSortOrder.length > 0">
3+
<h1 class="card-title">Previous sort order</h1>
4+
<h2 class="card-text">{{ previousSortOrder }}</h2>
5+
</div>
26
<div class="card-body">
3-
<h1 class="card-title">Sort order</h1>
4-
<h2 class="card-text">{{ sortOrder }}</h2>
7+
<h1 class="card-title">Current sort order</h1>
8+
<h2 class="card-text">{{ currentSortOrder }}</h2>
59
</div>
610
</div>
711
<div class="example-container">
812
<ngsg-card *ngFor="let item of items"
9-
ngSortgridItem
10-
ngSortGridGroup="react-on-changes"
11-
[item]="item"
12-
[ngSortGridItems]="items"
13-
(sorted)="applyOrder($event)"
14-
class="example-box">
13+
ngSortgridItem
14+
ngSortGridGroup="react-on-changes"
15+
[item]="item"
16+
[ngSortGridItems]="items"
17+
(sorted)="applyOrder($event)"
18+
class="example-box">
1519
{{ item }}
1620
</ngsg-card>
1721
</div>
Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {Component, OnInit} from '@angular/core';
2+
import {NgsgOrderChange} from '../../../../../../ng-sortgrid/src/lib/shared/ngsg-order-change.model';
23

34
@Component({
45
selector: 'ngsg-demo-react-on-changes-memory',
@@ -7,14 +8,17 @@ import {Component, OnInit} from '@angular/core';
78
export class ReactOnChangesMemoryComponent implements OnInit {
89

910
public items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
10-
public sortOrder: number[];
11+
public currentSortOrder: number[];
12+
public previousSortOrder: number[];
1113

1214
ngOnInit(): void {
13-
this.sortOrder = [...this.items];
15+
this.currentSortOrder = [...this.items];
16+
this.previousSortOrder = [];
1417
}
1518

16-
public applyOrder(newOrder: number[]): void {
17-
this.sortOrder = newOrder;
19+
public applyOrder(orderChange: NgsgOrderChange<number>): void {
20+
this.currentSortOrder = orderChange.currentOrder;
21+
this.previousSortOrder = orderChange.previousOrder;
1822
}
1923

2024
}

projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {NgsgSelectionService} from './mutliselect/ngsg-selection.service';
77
import {NgsgReflectService} from './sort/reflection/ngsg-reflect.service';
88
import {NgsgStoreService} from './store/ngsg-store.service';
99
import {NgsgEventsService} from './shared/ngsg-events.service';
10+
import {NgsgOrderChange} from './shared/ngsg-order-change.model';
1011

1112
describe('NgsgItemDirective', () => {
1213
let sut: NgsgItemDirective;
@@ -24,7 +25,8 @@ describe('NgsgItemDirective', () => {
2425
'resetSelectedItems',
2526
'hasGroup',
2627
'hasItems',
27-
'setItems'
28+
'setItems',
29+
'getItems'
2830
]);
2931
const ngsgEventService = new NgsgEventsService();
3032
const scrollHelperService = {
@@ -116,6 +118,7 @@ describe('NgsgItemDirective', () => {
116118

117119
it('should sort if the group contains selectedItems', () => {
118120
ngsgStore.hasSelectedItems.and.returnValue(true);
121+
ngsgStore.getItems.and.returnValue([]);
119122
ngsgStore.hasItems.and.returnValue(true);
120123
sut.drop();
121124
expect(ngsgSortService.endSort).toHaveBeenCalled();
@@ -125,34 +128,41 @@ describe('NgsgItemDirective', () => {
125128
const group = 'test-group';
126129
sut.ngSortGridGroup = group;
127130
ngsgStore.hasSelectedItems.and.returnValue(true);
131+
ngsgStore.getItems.and.returnValue([]);
128132

129133
sut.drop();
130134
expect(ngsgReflectService.reflectChanges).toHaveBeenCalledWith(group, elementRef.nativeElement);
131135
});
132136

133-
it('should get the reflected changes from the reflection service and emit them', done => {
137+
it('should emit a OrderChange containing the previous item order and the new itemorder', done => {
134138
const group = 'test-group';
135-
const reflectedChanges = ['item two', 'item one', 'item three'];
139+
const currentItemOrder = ['item one', 'item two', 'item three'];
140+
const newItemOrder = ['item two', 'item one', 'item three'];
141+
const expectedOrderChange: NgsgOrderChange<string> = {previousOrder: currentItemOrder, currentOrder: newItemOrder};
136142

137143
ngsgStore.hasSelectedItems.and.returnValue(true);
138144
ngsgStore.hasItems.and.returnValue(true);
139-
ngsgReflectService.reflectChanges.and.returnValue(reflectedChanges);
145+
ngsgStore.getItems.and.returnValue(currentItemOrder);
146+
ngsgReflectService.reflectChanges.and.returnValue(newItemOrder);
140147
sut.ngSortGridGroup = group;
141148

142-
sut.sorted.subscribe(changes => {
143-
expect(reflectedChanges).toEqual(changes);
149+
sut.sorted.subscribe((orderChange: NgsgOrderChange<string>) => {
150+
expect(orderChange).toEqual(expectedOrderChange);
144151
done();
145152
});
146153
sut.drop();
147-
expect(ngsgReflectService.reflectChanges).toHaveBeenCalledWith(group, elementRef.nativeElement);
148154
});
149155

150156
it('should reset the selected items on drop', () => {
157+
ngsgStore.hasSelectedItems.and.returnValue(true);
158+
ngsgStore.hasItems.and.returnValue(true);
151159
sut.drop();
152160
expect(ngsgStore.resetSelectedItems).toHaveBeenCalled();
153161
});
154162

155163
it('should stream the dropped event on the eventservice', done => {
164+
ngsgStore.hasSelectedItems.and.returnValue(true);
165+
ngsgStore.hasItems.and.returnValue(true);
156166
ngsgEventService.dropped$.subscribe(() => done());
157167
sut.drop();
158168
});

projects/ng-sortgrid/src/lib/ngsg-item.directive.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,32 @@ import {
1212
SimpleChanges
1313
} from '@angular/core';
1414

15-
import {fromEvent, Observable, Subject} from 'rxjs';
15+
import {fromEvent, Subject} from 'rxjs';
1616
import {takeUntil, takeWhile, throttleTime} from 'rxjs/operators';
17+
1718
import {NgsgSortService} from './sort/sort/ngsg-sort.service';
1819
import {NgsgSelectionService} from './mutliselect/ngsg-selection.service';
1920
import {NgsgReflectService} from './sort/reflection/ngsg-reflect.service';
2021
import {NgsgStoreService} from './store/ngsg-store.service';
2122
import {NgsgEventsService} from './shared/ngsg-events.service';
2223
import {ScrollHelperService} from './helpers/scroll/scroll-helper.service';
24+
import {NgsgOrderChange} from './shared/ngsg-order-change.model';
2325

2426
const selector = '[ngSortgridItem]';
2527

2628
@Directive({selector})
2729
export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDestroy {
2830
@Input() ngSortGridGroup = 'defaultGroup';
29-
@Input() ngSortGridItems;
30-
@Input() scrollPointTop;
31-
@Input() scrollPointBottom;
32-
@Input() scrollSpeed;
31+
@Input() ngSortGridItems: any[];
32+
@Input() scrollPointTop: number;
33+
@Input() scrollPointBottom: number;
34+
@Input() scrollSpeed: number;
3335
@Input() autoScroll = false;
3436

35-
@Output() sorted = new EventEmitter<any>();
37+
@Output() sorted = new EventEmitter<NgsgOrderChange<any>>();
3638

3739
private selected = false;
3840
private destroy$ = new Subject();
39-
private drag$: Observable<Event>;
4041

4142
constructor(
4243
public el: ElementRef,
@@ -124,10 +125,10 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe
124125
otherwhise the ordered items can not be emitted in the (sorted) event`);
125126
return;
126127
}
127-
128+
const previousOrder = [...this.ngsgStore.getItems(this.ngSortGridGroup)];
128129
this.sortService.endSort();
129-
const reflectedChanges = this.reflectService.reflectChanges(this.ngSortGridGroup, this.el.nativeElement);
130-
this.sorted.next(reflectedChanges);
130+
const currentOrder = this.reflectService.reflectChanges(this.ngSortGridGroup, this.el.nativeElement);
131+
this.sorted.next({previousOrder, currentOrder});
131132
this.ngsgStore.resetSelectedItems(this.ngSortGridGroup);
132133
this.ngsgEventService.dropped$.next();
133134
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export interface NgsgOrderChange<T> {
2+
previousOrder: T[];
3+
currentOrder: T[];
4+
}

projects/ng-sortgrid/src/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
*/
44
export * from './lib/ngsg-item.directive';
55
export * from './lib/ngsg.module';
6+
export * from './lib/shared/ngsg-order-change.model';

0 commit comments

Comments
 (0)