Skip to content

Commit

Permalink
feat: expose idsSelected computed signal in multi selection
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Guerrero authored and gabrielguerrero committed Apr 29, 2024
1 parent 21626e4 commit dc9a07e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ export type NamedEntitiesMultiSelectionState<Collection extends string> = {
};
export type EntitiesMultiSelectionComputed<Entity> = {
entitiesSelected: Signal<Entity[]>;
entitiesSelectedIds: Signal<(string | number)[]>;
isAllEntitiesSelected: Signal<'all' | 'none' | 'some'>;
};
export type NamedEntitiesMultiSelectionComputed<
Entity,
Collection extends string,
> = {
[K in Collection as `${K}SelectedEntities`]: Signal<Entity[]>;
} & {
[K in Collection as `${K}SelectedIds`]: Signal<Entity[]>;
} & {
[K in Collection as `isAll${Capitalize<string & K>}Selected`]: Signal<
'all' | 'none' | 'some'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('withEntitiesMultiSelection', () => {
const store = new Store();
patchState(store, setAllEntities(mockProducts));
store.selectEntities({ ids: [mockProducts[4].id, mockProducts[8].id] });
expect(store.entitiesSelectedIds()).toEqual(['4', '8']);
expect(store.entitiesSelected()).toEqual([
mockProducts[4],
mockProducts[8],
Expand All @@ -28,6 +29,7 @@ describe('withEntitiesMultiSelection', () => {
patchState(store, setAllEntities(mockProducts));
store.selectEntities({ ids: [mockProducts[4].id, mockProducts[8].id] });
store.deselectEntities({ ids: [mockProducts[4].id, mockProducts[8].id] });
expect(store.entitiesSelectedIds()).toEqual([]);
expect(store.entitiesSelected()).toEqual([]);
});

Expand All @@ -36,17 +38,21 @@ describe('withEntitiesMultiSelection', () => {
patchState(store, setAllEntities(mockProducts));
store.toggleSelectEntities({ id: mockProducts[4].id });
expect(store.entitiesSelected()).toEqual([mockProducts[4]]);
expect(store.entitiesSelectedIds()).toEqual(['4']);
store.toggleSelectEntities({ id: mockProducts[4].id });
expect(store.entitiesSelected()).toEqual([]);
expect(store.entitiesSelectedIds()).toEqual([]);
});

it('toggleSelectAllEntities should toggle selection of the entity', () => {
const store = new Store();
patchState(store, setAllEntities(mockProducts));
store.toggleSelectAllEntities();
expect(store.entitiesSelected().length).toEqual(mockProducts.length);
expect(store.entitiesSelectedIds().length).toEqual(mockProducts.length);
store.toggleSelectAllEntities();
expect(store.entitiesSelected()).toEqual([]);
expect(store.entitiesSelectedIds()).toEqual([]);
});

it('isAllEntitiesSelected should toggle selection of the entity', () => {
Expand Down Expand Up @@ -75,6 +81,7 @@ describe('withEntitiesMultiSelection', () => {
store.selectProductsEntities({
ids: [mockProducts[4].id, mockProducts[8].id],
});
expect(store.productsSelectedIds()).toEqual(['4', '8']);
expect(store.productsSelectedEntities()).toEqual([
mockProducts[4],
mockProducts[8],
Expand All @@ -91,15 +98,18 @@ describe('withEntitiesMultiSelection', () => {
ids: [mockProducts[4].id, mockProducts[8].id],
});
expect(store.productsSelectedEntities()).toEqual([]);
expect(store.productsSelectedIds()).toEqual([]);
});

it('toggle[Collection]Entities should toggle selection of the entity', () => {
const store = new Store();
patchState(store, setAllEntities(mockProducts, { collection }));
store.toggleSelectProductsEntities({ id: mockProducts[4].id });
expect(store.productsSelectedEntities()).toEqual([mockProducts[4]]);
expect(store.productsSelectedIds()).toEqual(['4']);
store.toggleSelectProductsEntities({ id: mockProducts[4].id });
expect(store.productsSelectedEntities()).toEqual([]);
expect(store.productsSelectedIds()).toEqual([]);
});

it('isAll[Collection]Selected should toggle selection of the entity', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { computed, Signal } from '@angular/core';
import { computed, effect, Signal } from '@angular/core';
import {
patchState,
signalStoreFeature,
SignalStoreFeature,
withComputed,
withHooks,
withMethods,
withState,
} from '@ngrx/signals';
Expand Down Expand Up @@ -36,6 +37,9 @@ function getEntitiesMultiSelectionKeys(config?: { collection?: string }) {
selectedEntitiesKey: collection
? `${config.collection}SelectedEntities`
: 'entitiesSelected',
selectedEntitiesIdsKey: collection
? `${config.collection}SelectedIds`
: 'entitiesSelectedIds',
selectEntitiesKey: collection
? `select${capitalizedProp}Entities`
: 'selectEntities',
Expand Down Expand Up @@ -179,6 +183,7 @@ export function withEntitiesMultiSelection<
const {
selectedIdsMapKey,
selectedEntitiesKey,
selectedEntitiesIdsKey,
deselectEntitiesKey,
toggleSelectEntitiesKey,
clearEntitiesSelectionKey,
Expand All @@ -197,7 +202,7 @@ export function withEntitiesMultiSelection<
const selectedIdsArray = computed(() =>
Object.entries(selectedIdsMap()).reduce(
(aux, [id, selected]) => {
if (selected) {
if (selected && entityMap()[id]) {
aux.push(id);
}
return aux;
Expand All @@ -206,6 +211,7 @@ export function withEntitiesMultiSelection<
),
);
return {
[selectedEntitiesIdsKey]: selectedIdsArray,
[selectedEntitiesKey]: computed(() => {
return selectedIdsArray().map((id) => entityMap()[id]);
}),
Expand Down

0 comments on commit dc9a07e

Please sign in to comment.