From 0db7f1eb966008a7a2b4437a8632bc7bf19bfa15 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Thu, 25 Apr 2019 08:38:16 +0200 Subject: [PATCH 1/5] fix(asyncpipe): support async pipe --- .../src/lib/ngsg-item.directive.ts | 30 ++++++++++++++----- .../ng-sortgrid/src/lib/ngsg-store.service.ts | 9 ++++++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts index 4ccab53..970f5f7 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-item.directive.ts @@ -5,9 +5,9 @@ import { EventEmitter, HostListener, Input, - NgZone, OnDestroy, + NgZone, OnChanges, OnDestroy, OnInit, - Output + Output, SimpleChanges } from '@angular/core'; import {NgsgReflectService} from './ngsg-reflect.service'; @@ -19,11 +19,12 @@ import {NgsgElementsHelper} from './ngsg-elements.helper'; import {NgsgEventsService} from './ngsg-events.service'; import {Subject} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; +import {group} from '@angular/animations'; const selector = '[ngSortgridItem]'; @Directive({selector}) -export class NgsgItemDirective implements OnInit, AfterViewInit, OnDestroy { +export class NgsgItemDirective implements OnInit, OnChanges, AfterViewInit, OnDestroy { @Input() ngSortGridGroup = 'defaultGroup'; @Input() ngSortGridItems; @@ -43,16 +44,22 @@ export class NgsgItemDirective implements OnInit, AfterViewInit, OnDestroy { } ngOnInit(): void { - if (!this.ngSortGridItems) { - console.warn(`Ng-sortgrid: No items provided - please use [sortGridItems] to pass in an array of items - - otherwhise the ordered items will not be emitted in the (sorted) event`); - } - this.ngsgStore.initState(this.ngSortGridGroup, this.ngSortGridItems, {}); this.ngsgEventService.dropped$.pipe( takeUntil(this.destroy$) ).subscribe(() => this.selected = false); } + ngOnChanges(changes: SimpleChanges): void { + const sortGridItemChanges = changes.ngSortGridItems; + const sortGridItems = sortGridItemChanges.currentValue ? sortGridItemChanges.currentValue : []; + + if (!this.ngsgStore.hasGroup(this.ngSortGridGroup)) { + this.ngsgStore.initState(this.ngSortGridGroup, sortGridItems); + return; + } + this.ngsgStore.setItems(this.ngSortGridGroup, sortGridItems); + } + ngAfterViewInit(): void { this.el.nativeElement.draggable = true; } @@ -94,6 +101,13 @@ export class NgsgItemDirective implements OnInit, AfterViewInit, OnDestroy { if (!this.ngsgStore.hasSelectedItems(this.ngSortGridGroup)) { return; } + + if (!this.ngsgStore.hasItems(this.ngSortGridGroup)) { + console.warn(`Ng-sortgrid: No items provided - please use [sortGridItems] to pass in an array of items - + otherwhise the ordered items can not be emitted in the (sorted) event`); + return; + } + this.sortService.endSort(); const element = !this.occuredOnHost(event) ? NgsgElementsHelper.findHost(event.target, selector) : event.target; const reflectedChanges = this.reflectService.reflectChanges(this.ngSortGridGroup, element); diff --git a/projects/ng-sortgrid/src/lib/ngsg-store.service.ts b/projects/ng-sortgrid/src/lib/ngsg-store.service.ts index 0605487..2d210c9 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-store.service.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-store.service.ts @@ -29,6 +29,7 @@ export class NgsgStoreService { } public setItems(group: string, items: any): void { + console.log('Items', items); this.state.get(group).items = [...items]; } @@ -36,6 +37,14 @@ export class NgsgStoreService { return this.state.get(group).items; } + public hasItems(group: string): boolean { + return this.getItems(group).length > 0; + } + + public hasGroup(group: string): boolean { + return this.state.has(group); + } + public getSelectedItems(group: string): NgsgDragelement[] { return this.state.get(group).selectedItems; } From 19513376fd9ae628535392c30ccf025afc17af16 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Sun, 28 Apr 2019 12:53:24 +0200 Subject: [PATCH 2/5] test(asyncpipe): fix failing tests --- .../src/lib/ngsg-item.directive.spec.ts | 76 ++++++++++++++----- .../src/lib/ngsg-store.service.spec.ts | 31 ++++++++ .../ng-sortgrid/src/lib/ngsg-store.service.ts | 1 - 3 files changed, 88 insertions(+), 20 deletions(-) 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 24a88ce..b50ef2b 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-item.directive.spec.ts @@ -19,7 +19,7 @@ describe('NgsgItemDirective', () => { ['selectElementIfNoSelection', 'updateSelectedDragItem']); const ngsgReflectService = createSpyObj('ngsgReflectService', ['reflectChanges']); const ngsgStore = createSpyObj('ngsgStore', - ['initState', 'hasSelectedItems', 'resetSelectedItems']); + ['initState', 'hasSelectedItems', 'resetSelectedItems', 'hasGroup', 'hasItems', 'setItems']); const ngsgEventService = new NgsgEventsService(); beforeEach(() => { @@ -27,24 +27,6 @@ describe('NgsgItemDirective', () => { ngsgReflectService, ngsgStore, ngsgEventService); }); - it('should log a warning if we do not pass in sort grid items', () => { - const consoleWarnSpy = spyOn(global.console, 'warn'); - sut.ngOnInit(); - expect(consoleWarnSpy).toHaveBeenCalledWith( - `Ng-sortgrid: No items provided - please use [sortGridItems] to pass in an array of items - - otherwhise the ordered items will not be emitted in the (sorted) event`); - }); - - it('should init the store with the sortGridGroup, the ngSortGridItems and the classes', () => { - const sortGridGroup = 'sortgridgroup'; - const sortGridItems = ['item one', 'item two', 'item three'] as any; - sut.ngSortGridItems = sortGridItems; - sut.ngSortGridGroup = sortGridGroup; - - sut.ngOnInit(); - expect(ngsgStore.initState).toHaveBeenCalledWith(sortGridGroup, sortGridItems, {}); - }); - it('should set the draggable attribute on the elment', () => { sut.ngAfterViewInit(); expect((elementRef.nativeElement as any).draggable).toBeTruthy(); @@ -133,6 +115,7 @@ describe('NgsgItemDirective', () => { it('should sort if the group contains selectedItems', () => { ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.hasItems.and.returnValue(true); sut.drop({target: {matches: () => true}}); expect(ngsgSortService.endSort).toHaveBeenCalled(); }); @@ -169,6 +152,7 @@ describe('NgsgItemDirective', () => { const reflectedChanges = ['item two', 'item one', 'item three']; ngsgStore.hasSelectedItems.and.returnValue(true); + ngsgStore.hasItems.and.returnValue(true); ngsgReflectService.reflectChanges.and.returnValue(reflectedChanges); sut.ngSortGridGroup = group; @@ -212,4 +196,58 @@ describe('NgsgItemDirective', () => { expect(ngsgSelectionService.updateSelectedDragItem).toHaveBeenCalledWith(group, host, true); }); + it(`should init the state with empty items if group has yet not been + initialized and the currentValue is null`, () => { + const group = 'test-group'; + const changes = { + ngSortGridItems: { + currentValue: null + } + } as any; + sut.ngSortGridGroup = group; + ngsgStore.hasGroup.and.returnValue(false); + + sut.ngOnChanges(changes); + expect(ngsgStore.initState).toHaveBeenCalledWith(group, []); + }); + + it('should init the state with items from the currentValue if group has yet not been initialized', () => { + const group = 'test-group'; + const changes = { + ngSortGridItems: { + currentValue: null + } + } as any; + sut.ngSortGridGroup = group; + ngsgStore.hasGroup.and.returnValue(false); + + sut.ngOnChanges(changes); + expect(ngsgStore.initState).toHaveBeenCalledWith(group, []); + }); + + it('should set the items if the group has allready been initialized', () => { + const group = 'test-group'; + const items = ['Item one', 'item two']; + const changes = { + ngSortGridItems: { + currentValue: items + } + } as any; + sut.ngSortGridGroup = group; + ngsgStore.hasGroup.and.returnValue(true); + + sut.ngOnChanges(changes); + expect(ngsgStore.setItems).toHaveBeenCalledWith(group, items); + }); + + it('should log a warning message if you drop and you did not provide any items', () => { + const expectedWarniningMessage = `Ng-sortgrid: No items provided - please use [sortGridItems] to pass in an array of items - + otherwhise the ordered items can not be emitted in the (sorted) event`; + const consoleWarnSpy = spyOn(console, 'warn'); + ngsgStore.hasItems.and.returnValue(false); + + sut.drop(event); + expect(consoleWarnSpy).toHaveBeenCalledWith(expectedWarniningMessage); + }); + }); diff --git a/projects/ng-sortgrid/src/lib/ngsg-store.service.spec.ts b/projects/ng-sortgrid/src/lib/ngsg-store.service.spec.ts index e65a379..f39cfd6 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-store.service.spec.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-store.service.spec.ts @@ -29,6 +29,37 @@ describe('NgsgStoreService', () => { expect(sut.getItems(group)).toEqual([]); }); + it('should return false if the group does not contain items', () => { + const group = 'testgroup'; + sut.initState(group); + + const hasItems = sut.hasItems(group); + expect(hasItems).toBeFalsy(); + }); + + it('should return true if the group contains items', () => { + const group = 'testgroup'; + sut.initState(group, ['item one', 'item two']); + + const hasItems = sut.hasItems(group); + expect(hasItems).toBeTruthy(); + }); + + it('should return false if the current group has yet not been initialized', () => { + const group = 'testgroup'; + + const hasGroup = sut.hasGroup(group); + expect(hasGroup).toBeFalsy(); + }); + + it('should return true if the current group has been initialized', () => { + const group = 'testgroup'; + sut.initState(group); + + const hasGroup = sut.hasGroup(group); + expect(hasGroup).toBeTruthy(); + }); + it('should add the classes to the group', () => { const group = 'testgroup'; const items = ['Item1', 'Item2']; diff --git a/projects/ng-sortgrid/src/lib/ngsg-store.service.ts b/projects/ng-sortgrid/src/lib/ngsg-store.service.ts index 2d210c9..2bbfb8a 100644 --- a/projects/ng-sortgrid/src/lib/ngsg-store.service.ts +++ b/projects/ng-sortgrid/src/lib/ngsg-store.service.ts @@ -29,7 +29,6 @@ export class NgsgStoreService { } public setItems(group: string, items: any): void { - console.log('Items', items); this.state.get(group).items = [...items]; } From e325ebc3c57684e9f047ef54001b6cd1accc7803 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Sun, 28 Apr 2019 12:57:33 +0200 Subject: [PATCH 3/5] docs(asyncpipe): adjust README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dfc31d5..9b5c0f3 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Import the ```NgsgModule``` in your ```AppModule```. ``` ## Apply the directive -Loop over your elements with *ngFor. 🛎️ the items needs to be an array. +Loop over your elements with *ngFor. 🛎️ the items needs to be an array. Alternate you can also use the async pipe to pass in your items. ![Grid demo](https://raw.githubusercontent.com/kreuzerk/ng-sortgrid/master/projects/ng-sortgrid-demo/src/assets/gs1.png) From 4758650ab23ceb078ddd3754e904c189cac8e967 Mon Sep 17 00:00:00 2001 From: kreuzerk Date: Sun, 28 Apr 2019 13:38:23 +0200 Subject: [PATCH 4/5] docs(asyncpipe): add async pipe demo example --- .../src/app/app.component.html | 7 ++- .../ng-sortgrid-demo/src/app/app.module.ts | 4 +- .../async-pipe-memory.component.css | 41 ++++++++++++++++++ .../async-pipe-memory.component.html | 21 +++++++++ .../async-pipe/async-pipe-memory.component.ts | 28 ++++++++++++ projects/ng-sortgrid-demo/src/assets/gs6.png | Bin 0 -> 83807 bytes 6 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 projects/ng-sortgrid-demo/src/app/examples/async-pipe/async-pipe-memory.component.css create mode 100644 projects/ng-sortgrid-demo/src/app/examples/async-pipe/async-pipe-memory.component.html create mode 100644 projects/ng-sortgrid-demo/src/app/examples/async-pipe/async-pipe-memory.component.ts create mode 100644 projects/ng-sortgrid-demo/src/assets/gs6.png diff --git a/projects/ng-sortgrid-demo/src/app/app.component.html b/projects/ng-sortgrid-demo/src/app/app.component.html index ae7c632..94c3ff7 100644 --- a/projects/ng-sortgrid-demo/src/app/app.component.html +++ b/projects/ng-sortgrid-demo/src/app/app.component.html @@ -3,7 +3,7 @@

1. Getting started

- + @@ -22,6 +22,11 @@

3. Group sortgrids

one group in another group.

+ +
+

4. Use the async pipe

+ +