Skip to content

Commit

Permalink
feat(signals): withEntitiesLocalSort should sort by default when with…
Browse files Browse the repository at this point in the history
…CallStatus is set to loaded

fix #80
  • Loading branch information
Gabriel Guerrero authored and gabrielguerrero committed May 22, 2024
1 parent 48778c4 commit 63a9986
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { TestBed } from '@angular/core/testing';
import { patchState, signalStore, type } from '@ngrx/signals';
import { setAllEntities, withEntities } from '@ngrx/signals/entities';

import { withEntitiesLocalSort } from '../index';
import { withCallStatus, withEntitiesLocalSort } from '../index';
import { mockProducts } from '../test.mocks';
import { Product } from '../test.model';

Expand Down Expand Up @@ -96,4 +97,73 @@ describe('withEntitiesLocalSort', () => {
direction: 'desc',
});
});

it('should sort entities using default when withCallStatus loaded', () => {
TestBed.runInInjectionContext(() => {
const Store = signalStore(
withEntities({
entity,
}),
withCallStatus(),
withEntitiesLocalSort({
entity,
defaultSort: { field: 'name', direction: 'asc' },
}),
);
const store = new Store();
patchState(store, setAllEntities(mockProducts));
store.setLoaded();
TestBed.flushEffects();
expect(store.entitiesSort()).toEqual({ field: 'name', direction: 'asc' });
// check default sort
expect(
store
.entities()
.map((e) => e.name)
.slice(0, 5),
).toEqual([
'1080° Avalanche',
'Animal Crossing',
'Arkanoid: Doh it Again',
'Battalion Wars',
'BattleClash',
]);
});
});

it('with collection should sort entities using default when withCallStatus loaded', () => {
TestBed.runInInjectionContext(() => {
const collection = 'products';
const Store = signalStore(
withEntities({
entity,
collection,
}),
withCallStatus({ collection }),
withEntitiesLocalSort({
entity,
collection,
defaultSort: { field: 'name', direction: 'asc' },
}),
);
const store = new Store();
patchState(store, setAllEntities(mockProducts, { collection }));
store.setProductsLoaded();
TestBed.flushEffects();
expect(store.productsSort()).toEqual({ field: 'name', direction: 'asc' });
// check default sort
expect(
store
.productsEntities()
.map((e) => e.name)
.slice(0, 5),
).toEqual([
'1080° Avalanche',
'Animal Crossing',
'Arkanoid: Doh it Again',
'Battalion Wars',
'BattleClash',
]);
});
});
});
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { Signal } from '@angular/core';
import { effect, Signal, untracked } from '@angular/core';
import {
patchState,
signalStoreFeature,
SignalStoreFeature,
withHooks,
withMethods,
withState,
} from '@ngrx/signals';
Expand All @@ -18,6 +19,7 @@ import {
import type { StateSignal } from '@ngrx/signals/src/state-signal';

import { getWithEntitiesKeys } from '../util';
import { getWithCallStatusKeys } from '../with-call-status/with-call-status.util';
import {
broadcast,
withEventHandler,
Expand Down Expand Up @@ -142,6 +144,7 @@ export function withEntitiesLocalSort<
const { entitiesKey } = getWithEntitiesKeys(config);
const { sortEntitiesKey, sortKey } = getWithEntitiesSortKeys(config);
const { entitiesLocalSortChanged } = getWithEntitiesLocalSortEvents(config);

return signalStoreFeature(
withState({ [sortKey]: defaultSort }),
withEventHandler(),
Expand Down Expand Up @@ -171,5 +174,23 @@ export function withEntitiesLocalSort<
},
};
}),
withHooks((state: Record<string, unknown>) => {
const { loadedKey } = getWithCallStatusKeys({ prop: config?.collection });
const loaded = state[loadedKey] as Signal<boolean> | undefined;
return {
onInit: () => {
if (loaded) {
const sortEntities = state[sortEntitiesKey] as () => void;
effect(() => {
if (loaded()) {
untracked(() => {
sortEntities();
});
}
});
}
},
};
}),
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export function sortData<T>(data: T[], sort: Sort<T>): T[] {
if (!active || direction === '') {
return data;
}

return data.sort((a, b) => {
const valueA = sortingDataAccessor(a, active as string);
const valueB = sortingDataAccessor(b, active as string);
Expand Down

0 comments on commit 63a9986

Please sign in to comment.