diff --git a/projects/data-grid-demo/src/app/app.component.html b/projects/data-grid-demo/src/app/app.component.html index 5d1670a..cd55111 100644 --- a/projects/data-grid-demo/src/app/app.component.html +++ b/projects/data-grid-demo/src/app/app.component.html @@ -2,3 +2,6 @@ [gridName]="gridName" [config]="config"> + + + diff --git a/projects/data-grid-demo/src/app/app.component.ts b/projects/data-grid-demo/src/app/app.component.ts index 5aef338..8dcaf2b 100644 --- a/projects/data-grid-demo/src/app/app.component.ts +++ b/projects/data-grid-demo/src/app/app.component.ts @@ -1,5 +1,5 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core'; -import { DataGridColumn, FilterType, GridConfig, GridConfigBuilder, hasData, initGrid } from 'ngrx-data-grid'; +import { DataGridColumn, FilterType, GridConfig, GridConfigBuilder, hasData, initGrid, updateGridData } from 'ngrx-data-grid'; import * as R from 'ramda'; import { NumberComponent } from './components/number.component'; import { MockService } from './mock/mock.service'; @@ -146,4 +146,15 @@ export class AppComponent implements OnInit { }]; } + onUpdateMailOfFirstElement(newMailValue) { + const firstElementId = 'd66f8066-547f-41ff-b9b8-ae3a0e10705d'; + this.store.dispatch(updateGridData({ + name: 'gridTest', + shouldUpdate: (gridElement) => gridElement.userId === firstElementId, + update: (gridElement) => R.mergeRight(gridElement, { + mail: newMailValue + }) + })); + } + } diff --git a/projects/data-grid/src/lib/actions/data-grid-actions.ts b/projects/data-grid/src/lib/actions/data-grid-actions.ts index 4087921..46085cc 100644 --- a/projects/data-grid/src/lib/actions/data-grid-actions.ts +++ b/projects/data-grid/src/lib/actions/data-grid-actions.ts @@ -1,4 +1,4 @@ -import {createAction, props} from '@ngrx/store'; +import { createAction, props } from '@ngrx/store'; import { ChangePageNumberPayload, ChangePageSizePayload, @@ -7,7 +7,8 @@ import { SortGridPayload, ToggleAllRowsSelectionPayload, ToggleColumnVisibilityPayload, - ToggleRowSelectionPayload + ToggleRowSelectionPayload, + UpdateGridDataPayload } from './data-grid-payload'; export enum GridActionTypes { @@ -18,7 +19,8 @@ export enum GridActionTypes { ChangePageNumber = 'ngrx-data-grid/ChangePageNumber', ToggleRowSelection = 'ngrx-data-grid/ToggleRowSelection', ToggleAllRowsSelection = 'ngrx-data-grid/ToggleAllRowsSelection', - ToggleColumnVisibility = 'ngrx-data-grid/ToggleColumnVisibility' + ToggleColumnVisibility = 'ngrx-data-grid/ToggleColumnVisibility', + UpdateGridData = 'ngrx-data-grid/UpdateGridData' } export const initGrid = createAction( @@ -62,3 +64,7 @@ export const toggleColumnVisibility = createAction( props() ); +export const updateGridData = createAction( + GridActionTypes.UpdateGridData, + props() +); diff --git a/projects/data-grid/src/lib/actions/data-grid-payload.ts b/projects/data-grid/src/lib/actions/data-grid-payload.ts index 3197189..7584c5a 100644 --- a/projects/data-grid/src/lib/actions/data-grid-payload.ts +++ b/projects/data-grid/src/lib/actions/data-grid-payload.ts @@ -39,3 +39,11 @@ export interface ToggleAllRowsSelectionPayload extends BaseGridPayload { export interface ToggleColumnVisibilityPayload extends BaseGridPayload { columnId: string; } + +type ShouldUpdateGridElement = (T) => boolean; +type UpdateGridElement = (T) => T; + +export interface UpdateGridDataPayload extends BaseGridPayload { + shouldUpdate: ShouldUpdateGridElement; + update: UpdateGridElement; +} diff --git a/projects/data-grid/src/lib/store/data-grid.spec.ts b/projects/data-grid/src/lib/store/data-grid.spec.ts index 49578d4..049abdd 100644 --- a/projects/data-grid/src/lib/store/data-grid.spec.ts +++ b/projects/data-grid/src/lib/store/data-grid.spec.ts @@ -1,14 +1,17 @@ import * as R from 'ramda'; -import { changePageNumber, changePageSize, initGrid, toggleAllRowsSelection, toggleColumnVisibility, toggleRowSelection, updateFilters, updateSort } from '../actions/data-grid-actions'; -import { gridReducer, initialState } from './data-grid'; import { - assignIdsToColumns, - columnFilterDefined, - columnSortType, - filterApplied, - FilteringOptions, - SortType -} from '../models'; + changePageNumber, + changePageSize, + initGrid, + toggleAllRowsSelection, + toggleColumnVisibility, + toggleRowSelection, + updateFilters, + updateGridData, + updateSort +} from '../actions/data-grid-actions'; +import { gridReducer, initialState } from './data-grid'; +import { assignIdsToColumns, columnFilterDefined, columnSortType, filterApplied, FilteringOptions, SortType } from '../models'; const findByProp = (props) => R.path(props); const getColumn: any = (id) => R.compose(R.find(R.propEq('columnId', id)), findByProp(['columns'])); @@ -230,4 +233,30 @@ describe('Data Grid reducer', () => { expect(column).toBeDefined(); expect(findByProp(['visible'])(column)).toBeTruthy(); }); + + it('should update one element of the grid data', () => { + const shouldUpdateFn = R.curry((gridId, gridElement) => gridElement.id === gridId); + const updateFn = (gridElement) => ({...gridElement, name: 'updated test'}); + const action = updateGridData({name: 'grid-1', shouldUpdate: shouldUpdateFn(1), update: updateFn}); + const expectedData = R.update(0, {id: 1, name: 'updated test', value: 20}, data); + + const result = R.prop('grid-1')(gridReducer(state, action)); + + expect(result.data).toEqual(expectedData); + }); + + it('should update more elements of the grid data', () => { + const shouldUpdateFn = R.curry((gridId, gridElement) => gridElement.id === gridId || gridElement.id === gridId + 1); + const updateFn = (gridElement) => ({...gridElement, name: 'updated test'}); + const action = updateGridData({name: 'grid-1', shouldUpdate: shouldUpdateFn(1), update: updateFn}); + const expectedData = R.compose( + R.update(0, {id: 1, name: 'updated test', value: 20}), + R.update(1, {id: 2, name: 'updated test', value: 40}) + )(data); + + const result = R.prop('grid-1')(gridReducer(state, action)); + + expect(result.data).toEqual(expectedData); + }); + }); diff --git a/projects/data-grid/src/lib/store/data-grid.ts b/projects/data-grid/src/lib/store/data-grid.ts index 71c0282..bc5c2c3 100644 --- a/projects/data-grid/src/lib/store/data-grid.ts +++ b/projects/data-grid/src/lib/store/data-grid.ts @@ -6,7 +6,7 @@ import { calculateNumberOfPages } from './pagination-util'; import { applySorting } from './sorting-util'; import { hasValue, isNotEqual, isTrue, mapIndexed } from '../util/type'; import { applyFilters } from './filters-util'; -import { FilterGridPayload, InitGridPayload, SortGridPayload } from '../actions/data-grid-payload'; +import { FilterGridPayload, InitGridPayload, SortGridPayload, UpdateGridDataPayload } from '../actions/data-grid-payload'; import { assignIdsToColumns, columnFilter, @@ -184,6 +184,12 @@ const recalculateRowIndexesAndPagination = (state: GridState): any => { }); }; +const updateGridData = (state: GridState, {shouldUpdate, update}: UpdateGridDataPayload): GridState => + R.evolve({ + data: R.map(R.ifElse(shouldUpdate, update, R.identity)) + }, state); + + // create reducer const reducer = createReducer( initialGridState, @@ -194,7 +200,8 @@ const reducer = createReducer( on(GridActions.changePageNumber, changePageNumberHandler), on(GridActions.toggleRowSelection, toggleRowSelectionHandler), on(GridActions.toggleAllRowsSelection, toggleAllRowsSelectionHandler), - on(GridActions.toggleColumnVisibility, toggleColumnVisibilityHandler) + on(GridActions.toggleColumnVisibility, toggleColumnVisibilityHandler), + on(GridActions.updateGridData, updateGridData) ); const rowIndexesAndPaginationReducer = createReducer(initialGridState, on( @@ -208,7 +215,7 @@ const rowIndexesAndPaginationReducer = createReducer(initialGridState, on( const isNgRxGridAction = R.startsWith('ngrx-data-grid'); -export function gridReducer (state = initialState, action) { +export function gridReducer(state = initialState, action) { if (!isNgRxGridAction(action.type)) { return state; }