From b69abafbe1fbb0491a0dffdca83a3af41931cac0 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Wed, 26 Feb 2020 13:30:45 +0100 Subject: [PATCH 1/3] feat(sort): emit previous and current change on sort event BREAKING CHANGE: The sort event now emits a NgsgOrderChange instead of an array --- .../async-pipe-memory.component.html | 8 +++++-- .../async-pipe/async-pipe-memory.component.ts | 20 +++++++++++----- .../react-on-changes-memory.component.html | 20 +++++++++------- .../react-on-changes-memory.component.ts | 12 ++++++---- .../src/lib/ngsg-item.directive.spec.ts | 24 +++++++++++++------ .../src/lib/ngsg-item.directive.ts | 13 +++++----- .../src/lib/shared/ngsg-order-change.model.ts | 4 ++++ projects/ng-sortgrid/src/public-api.ts | 1 + 8 files changed, 69 insertions(+), 33 deletions(-) create mode 100644 projects/ng-sortgrid/src/lib/shared/ngsg-order-change.model.ts diff --git a/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.html b/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.html index 4007be3..58adc05 100644 --- a/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.html +++ b/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.html @@ -1,9 +1,13 @@
4. Load items and use them with the async pipe
+
+

Previous sort order

+

{{ previousSortOrder }}

+
-

Sort order

-

{{ sortOrder }}

+

Current sort order

+

{{ currentSortOrder }}

diff --git a/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.ts b/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.ts index 6c2916d..076b3d5 100644 --- a/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.ts +++ b/projects/ng-sortgrid-demo/src/app/introduction/examples/async-pipe/async-pipe-memory.component.ts @@ -1,17 +1,25 @@ -import {Component} from '@angular/core'; +import {Component, OnInit} from '@angular/core'; import {Observable, of} from 'rxjs'; import {delay, tap} from 'rxjs/operators'; +import {NgsgOrderChange} from '../../../../../../ng-sortgrid/src/lib/shared/ngsg-order-change.model'; + @Component({ selector: 'ngsg-demo-async', templateUrl: './async-pipe-memory.component.html', styleUrls: ['./async-pipe-memory.component.css'] }) -export class AsyncPipeMemoryComponent { +export class AsyncPipeMemoryComponent implements OnInit { item$: Observable; loading = false; - public sortOrder: number[]; + public currentSortOrder: number[]; + public previousSortOrder: number[]; + + ngOnInit(): void { + this.previousSortOrder = []; + this.currentSortOrder = []; + } public loadItems(): void { this.loading = true; @@ -21,8 +29,8 @@ export class AsyncPipeMemoryComponent { ); } - public applyOrder(newOrder: number[]): void { - this.sortOrder = newOrder; + public applyOrder(orderChange: NgsgOrderChange): void { + this.currentSortOrder = orderChange.currentOrder; + this.previousSortOrder = orderChange.previousOrder; } - } diff --git a/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.html b/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.html index 3e1e486..e178322 100644 --- a/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.html +++ b/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.html @@ -1,17 +1,21 @@
+
+

Previous sort order

+

{{ previousSortOrder }}

+
-

Sort order

-

{{ sortOrder }}

+

Current sort order

+

{{ currentSortOrder }}

+ ngSortgridItem + ngSortGridGroup="react-on-changes" + [item]="item" + [ngSortGridItems]="items" + (sorted)="applyOrder($event)" + class="example-box"> {{ item }}
diff --git a/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.ts b/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.ts index f6ab716..39a503e 100644 --- a/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.ts +++ b/projects/ng-sortgrid-demo/src/app/introduction/examples/react-on-changes/react-on-changes-memory.component.ts @@ -1,4 +1,5 @@ import {Component, OnInit} from '@angular/core'; +import {NgsgOrderChange} from '../../../../../../ng-sortgrid/src/lib/shared/ngsg-order-change.model'; @Component({ selector: 'ngsg-demo-react-on-changes-memory', @@ -7,14 +8,17 @@ import {Component, OnInit} from '@angular/core'; export class ReactOnChangesMemoryComponent implements OnInit { public items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - public sortOrder: number[]; + public currentSortOrder: number[]; + public previousSortOrder: number[]; ngOnInit(): void { - this.sortOrder = [...this.items]; + this.currentSortOrder = [...this.items]; + this.previousSortOrder = []; } - public applyOrder(newOrder: number[]): void { - this.sortOrder = newOrder; + public applyOrder(orderChange: NgsgOrderChange): void { + this.currentSortOrder = orderChange.currentOrder; + this.previousSortOrder = orderChange.previousOrder; } } diff --git a/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts b/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts index 38e07e2..7c17042 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts @@ -7,6 +7,7 @@ import {NgsgSelectionService} from './mutliselect/ngsg-selection.service'; import {NgsgReflectService} from './sort/reflection/ngsg-reflect.service'; import {NgsgStoreService} from './store/ngsg-store.service'; import {NgsgEventsService} from './shared/ngsg-events.service'; +import {NgsgOrderChange} from './shared/ngsg-order-change.model'; describe('NgsgItemDirective', () => { let sut: NgsgItemDirective; @@ -24,7 +25,8 @@ describe('NgsgItemDirective', () => { 'resetSelectedItems', 'hasGroup', 'hasItems', - 'setItems' + 'setItems', + 'getItems' ]); const ngsgEventService = new NgsgEventsService(); const scrollHelperService = { @@ -116,6 +118,7 @@ describe('NgsgItemDirective', () => { it('should sort if the group contains selectedItems', () => { ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.getItems.and.returnValue([]); ngsgStore.hasItems.and.returnValue(true); sut.drop(); expect(ngsgSortService.endSort).toHaveBeenCalled(); @@ -125,34 +128,41 @@ describe('NgsgItemDirective', () => { const group = 'test-group'; sut.ngSortGridGroup = group; ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.getItems.and.returnValue([]); sut.drop(); expect(ngsgReflectService.reflectChanges).toHaveBeenCalledWith(group, elementRef.nativeElement); }); - it('should get the reflected changes from the reflection service and emit them', done => { + it('should emit a OrderChange containing the previous item order and the new itemorder', done => { const group = 'test-group'; - const reflectedChanges = ['item two', 'item one', 'item three']; + const currentItemOrder = ['item one', 'item two', 'item three']; + const newItemOrder = ['item two', 'item one', 'item three']; + const expectedOrderChange: NgsgOrderChange = {previousOrder: currentItemOrder, currentOrder: newItemOrder}; ngsgStore.hasSelectedItems.and.returnValue(true); ngsgStore.hasItems.and.returnValue(true); - ngsgReflectService.reflectChanges.and.returnValue(reflectedChanges); + ngsgStore.getItems.and.returnValue(currentItemOrder); + ngsgReflectService.reflectChanges.and.returnValue(newItemOrder); sut.ngSortGridGroup = group; - sut.sorted.subscribe(changes => { - expect(reflectedChanges).toEqual(changes); + sut.sorted.subscribe((orderChange: NgsgOrderChange) => { + expect(orderChange).toEqual(expectedOrderChange); done(); }); sut.drop(); - expect(ngsgReflectService.reflectChanges).toHaveBeenCalledWith(group, elementRef.nativeElement); }); it('should reset the selected items on drop', () => { + ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.hasItems.and.returnValue(true); sut.drop(); expect(ngsgStore.resetSelectedItems).toHaveBeenCalled(); }); it('should stream the dropped event on the eventservice', done => { + ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.hasItems.and.returnValue(true); ngsgEventService.dropped$.subscribe(() => done()); sut.drop(); }); diff --git a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts index a537d96..fe73d4a 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts @@ -12,14 +12,16 @@ import { SimpleChanges } from '@angular/core'; -import {fromEvent, Observable, Subject} from 'rxjs'; +import {fromEvent, Subject} from 'rxjs'; import {takeUntil, takeWhile, throttleTime} from 'rxjs/operators'; + import {NgsgSortService} from './sort/sort/ngsg-sort.service'; import {NgsgSelectionService} from './mutliselect/ngsg-selection.service'; import {NgsgReflectService} from './sort/reflection/ngsg-reflect.service'; import {NgsgStoreService} from './store/ngsg-store.service'; import {NgsgEventsService} from './shared/ngsg-events.service'; import {ScrollHelperService} from './helpers/scroll/scroll-helper.service'; +import {NgsgOrderChange} from './shared/ngsg-order-change.model'; const selector = '[ngSortgridItem]'; @@ -32,11 +34,10 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe @Input() scrollSpeed; @Input() autoScroll = false; - @Output() sorted = new EventEmitter(); + @Output() sorted = new EventEmitter>(); private selected = false; private destroy$ = new Subject(); - private drag$: Observable; constructor( public el: ElementRef, @@ -124,10 +125,10 @@ export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDe otherwhise the ordered items can not be emitted in the (sorted) event`); return; } - + const previousOrder = [...this.ngsgStore.getItems(this.ngSortGridGroup)]; this.sortService.endSort(); - const reflectedChanges = this.reflectService.reflectChanges(this.ngSortGridGroup, this.el.nativeElement); - this.sorted.next(reflectedChanges); + const currentOrder = this.reflectService.reflectChanges(this.ngSortGridGroup, this.el.nativeElement); + this.sorted.next({previousOrder, currentOrder}); this.ngsgStore.resetSelectedItems(this.ngSortGridGroup); this.ngsgEventService.dropped$.next(); } diff --git a/projects/ng-sortgrid/src/lib/shared/ngsg-order-change.model.ts b/projects/ng-sortgrid/src/lib/shared/ngsg-order-change.model.ts new file mode 100644 index 0000000..23b8b1c --- /dev/null +++ b/projects/ng-sortgrid/src/lib/shared/ngsg-order-change.model.ts @@ -0,0 +1,4 @@ +export interface NgsgOrderChange { + previousOrder: T[]; + currentOrder: T[]; +} diff --git a/projects/ng-sortgrid/src/public-api.ts b/projects/ng-sortgrid/src/public-api.ts index 9c5bfcb..ed9bceb 100644 --- a/projects/ng-sortgrid/src/public-api.ts +++ b/projects/ng-sortgrid/src/public-api.ts @@ -3,3 +3,4 @@ */ export * from './lib/ngsg-item.directive'; export * from './lib/ngsg.module'; +export * from './lib/shared/ngsg-order-change.model'; From 16eb1ee10c304a65d8bce088e666f6dc9d116630 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Wed, 26 Feb 2020 13:35:28 +0100 Subject: [PATCH 2/3] docs(readme): adjust readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index abd8ee0..cdddfa1 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ In most cases you are interested in the new sort order. Often you want to store Pass your items to the directive via the ngSortGridItems input. ![Grid demo](https://raw.githubusercontent.com/kreuzerk/ng-sortgrid/master/projects/ng-sortgrid-demo/src/assets/gs3.png) -React on the 'sorted' output events +React on the 'sorted' output event. The `sorted` output event emits a `NgsgOrderChange` which contains the `previousOrder` and the `currentOrder` ![Grid demo](https://raw.githubusercontent.com/kreuzerk/ng-sortgrid/master/projects/ng-sortgrid-demo/src/assets/gs4.png) From 0d6a078953af97ccee351aeb71971e65b19dabe7 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Wed, 26 Feb 2020 16:12:05 +0100 Subject: [PATCH 3/3] docs(api): document API --- README.md | 20 +++++++++++++++++++ .../src/lib/ngsg-item.directive.ts | 8 ++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index cdddfa1..70e136f 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ - [Download the module](#download-the-module) - [Apply the directive](#apply-the-directive) - [React on changes](#react-on-changes) +- [API](#api) + - [Inputs](#inputs) + - [Outputs](#outputs) # Getting started ## Download the module @@ -98,3 +101,20 @@ at the top of your page. In this case you need to scroll once you drag an elemen The *scrollSpeed* property accepts a number and allows you to specify the scrolling speed. [Check out the scroll demo](https://kreuzerk.github.io/ng-sortgrid/scrolling) + +# API + +## Inputs +| Value | Description | Default| +|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------|--------| +| ngSortGridGroup: string | Groups a grid - avoids that items from one grid can be dragged to another grid |undefined| +| ngSortGridItems: any[] | Sort grid items. Pass down a list of all your items. This list is needed to enable the sorting feature.|undefined| +| autoScroll: boolean | Flag to enable autoscrolling|false| +| scrollPointTop: number | Custom top scrollpoint in pixels|if autoscroll is applied we start scrolling if we pass the top border| +| scrollPointBottom: number | Custom bottom scrollpoint in pixels|if autoscroll is applied we start scrolling if we pass the bottom border| +| scrollSpeed: number | Scrollspeed, the higher the value, the higher we scroll.|50 - only applies if autoscrolling is on| + +## Outputs +| Value | Description | Default| +|-------------------|------------------------------------------------------------------------------------------------------------------------------------------------|--------| +| sorted: EventEmitter | Emits an event after we sorted the items, each event is of type NgsgOrderChange. The NgsgOrderChange contains the previousOrder and the currentOrder |undefined| diff --git a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts index fe73d4a..a7ecaec 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts @@ -28,10 +28,10 @@ const selector = '[ngSortgridItem]'; @Directive({selector}) export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDestroy { @Input() ngSortGridGroup = 'defaultGroup'; - @Input() ngSortGridItems; - @Input() scrollPointTop; - @Input() scrollPointBottom; - @Input() scrollSpeed; + @Input() ngSortGridItems: any[]; + @Input() scrollPointTop: number; + @Input() scrollPointBottom: number; + @Input() scrollSpeed: number; @Input() autoScroll = false; @Output() sorted = new EventEmitter>();