33 EntityId ,
44 EntityMap ,
55 removeEntity ,
6- SelectEntityId ,
6+ SelectEntityId , setAllEntities ,
77 setEntities ,
88 setEntity ,
99 withEntities
@@ -14,7 +14,8 @@ import { finalize, firstValueFrom, lastValueFrom, map, mergeMap, Observable, of
1414import { Signal } from '@angular/core' ;
1515import { ManagedData , XtTypeResolver } from 'xt-type' ;
1616import { XtStoreManager } from '../store-manager/xt-store-manager' ;
17- import { XtStoreCriteria } from '../xt-store-parameters' ;
17+ import { XtSortBy , XtStoreCriteria } from '../xt-store-parameters' ;
18+ import { XtStoreProviderHelper } from '../store-provider/xt-store-provider-helper' ;
1819
1920export function selectId < T extends ManagedData = ManagedData > ( ) : SelectEntityId < T > { return ( data ) => {
2021 if ( data . _id == null ) throw new Error ( "ManagedData with no entity Id used in the store." , { cause : data } ) ;
@@ -30,9 +31,11 @@ export function xtStoreEntityConfig<T extends ManagedData=ManagedData> () {
3031} ;
3132
3233
33- export type StoreState = {
34+ export type StoreState < T extends ManagedData = ManagedData > = {
3435 entityName : string ,
35- loading :boolean
36+ loading :boolean ,
37+ sort ?: XtSortBy < T > [ ] ,
38+ filter ?: XtStoreCriteria < T > [ ]
3639} ;
3740
3841export type XtSignalStore < T > = {
@@ -72,14 +75,14 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
7275 withMethods ( ( store ) => ( {
7376 async storeEntity ( toStore :T ) : Promise < T > {
7477 patchState ( store , { loading :true } ) ;
75- return this . clearReferences ( toStore ) . then ( ( valAndRef ) => {
78+ return this . _clearReferences ( toStore ) . then ( ( valAndRef ) => {
7679 return store . _storeProvider . storeEntity ( entityName , valAndRef . newValue ) . then ( ( stored ) => {
7780 return { newValue : stored , references : valAndRef . references } ;
7881 } ) ;
7982 } ) . then ( ( valAndRef ) => {
80- return this . applyReferences ( valAndRef . newValue , valAndRef . references ) ;
83+ return this . _applyReferences ( valAndRef . newValue , valAndRef . references ) ;
8184 } ) . then ( ( stored ) => {
82- patchState ( store , setEntity ( stored , store . _entityConfig ) ) ;
85+ this . _patchStateSetEntity ( stored ) ;
8386 return stored ;
8487 } ) . finally ( ( ) => {
8588 patchState ( store , { loading :false } ) ;
@@ -89,7 +92,7 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
8992 fetchEntities ( ) : Promise < void > {
9093 patchState ( store , { loading :true } ) ;
9194 return lastValueFrom ( store . _storeProvider . searchEntities ( entityName ) . pipe ( mergeMap ( ( entities :T [ ] ) => {
92- return this . resolveReferences ( entities ) ;
95+ return this . _resolveReferences ( entities ) ;
9396 } ) , map ( ( entities : T [ ] ) => {
9497 patchState ( store , setEntities ( entities , store . _entityConfig ) ) ;
9598 } ) , finalize ( ( ) => {
@@ -111,7 +114,7 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
111114 patchState ( store , { loading :true } ) ;
112115 return store . _storeProvider . loadEntity ( entityName , id ) . then ( ( loaded ) => {
113116 if ( loaded != null )
114- return this . resolveReferences ( [ loaded ] ) . then ( ( results ) => results [ 0 ] ) ;
117+ return this . _resolveReferences ( [ loaded ] ) . then ( ( results ) => results [ 0 ] ) ;
115118 return loaded ;
116119 } ) . then ( ( loaded ) => {
117120 if ( loaded != null )
@@ -149,17 +152,11 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
149152 patchState ( store , { loading : true } ) ;
150153 try {
151154 const listEntities = store . entities ( ) ;
152- let toAdd = true ;
153155 const ret = new Array < T > ( ) ;
154156 for ( const entity of listEntities ) {
155- toAdd = true ;
156- for ( const crit of criteria ) {
157- if ( ! crit . filter ( entity ) ) {
158- toAdd = false ;
159- break ;
160- }
157+ if ( ! this . _isFiltered ( entity , criteria ) ) {
158+ ret . push ( entity ) ;
161159 }
162- if ( toAdd ) ret . push ( entity ) ;
163160 }
164161 return of ( ret ) ;
165162 } finally {
@@ -171,7 +168,7 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
171168 * Detects and replace all referenced objects by the key value that will be stored.
172169 * @param toClear
173170 */
174- async clearReferences ( toClear : T ) : Promise < { newValue : T , references : any } > {
171+ async _clearReferences ( toClear : T ) : Promise < { newValue : T , references : any } > {
175172 if ( typeRegistry == null ) return { newValue :toClear , references :{ } } ;
176173
177174 const refs = typeRegistry . listReferences ( entityName ) ;
@@ -190,7 +187,7 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
190187 * From the key values, assign the relevant referenced object so that it's transparent to the caller
191188 * @param values
192189 */
193- async resolveReferences ( values : T [ ] ) : Promise < T [ ] > {
190+ async _resolveReferences ( values : T [ ] ) : Promise < T [ ] > {
194191 if ( ( typeRegistry == null ) || ( storeMgr == null ) ) return values ;
195192
196193 const refs = typeRegistry . listReferences ( entityName ) ;
@@ -217,11 +214,60 @@ export function withXtStoreProvider<T extends ManagedData = ManagedData> (entity
217214 * @param newValue
218215 * @param references
219216 */
220- async applyReferences ( newValue : T , references : ManagedData ) : Promise < T > {
217+ async _applyReferences ( newValue : T , references : ManagedData ) : Promise < T > {
221218 if ( references != null ) {
222219 // Override the values with the references
223220 return { ...newValue , ...references } as T ;
224221 } else return newValue ;
222+ } ,
223+
224+ _patchStateSetEntity ( stored :T ) {
225+ // Ensure the entity is still part of the list
226+ if ( this . _isFiltered ( stored ) == false ) {
227+ // It's still in the list, now check if sort needs to be applied
228+ if ( this . _safeSort ( ) . length > 0 ) {
229+ // We remove it from the old sort
230+ if ( stored . _id != null )
231+ patchState ( store , removeEntity ( stored . _id ) ) ;
232+
233+ // And find it's right position
234+ const newList = XtStoreProviderHelper . insertInSortedList ( stored , store . entities ( ) , this . _safeSort ( ) ) ;
235+ patchState ( store , setAllEntities ( newList , store . _entityConfig ) ) ;
236+ } else {
237+ patchState ( store , setEntity ( stored , store . _entityConfig ) ) ;
238+ }
239+ } else {
240+ // Maybe it was in the list and it is no more due to the modification. Let's make sure by removing it
241+ if ( stored . _id != null )
242+ patchState ( store , removeEntity ( stored . _id ) ) ;
243+ }
244+
245+ } ,
246+ _isFiltered ( element :T , criteria ?:XtStoreCriteria < T > [ ] ) :boolean {
247+ if ( criteria === undefined ) {
248+ criteria = this . _safeFilter ( ) ;
249+ }
250+ for ( const crit of criteria ) {
251+ if ( crit . filter ( element ) ) {
252+ return true ;
253+ }
254+
255+ }
256+ return false ;
257+ } ,
258+ _safeFilter ( ) : XtStoreCriteria < T > [ ] {
259+ const ret = store . filter ?store . filter ( ) :null ;
260+ if ( ( ret != null ) && ( ret . length > 0 ) ) {
261+ return ret ;
262+ }
263+ return [ ] ;
264+ } ,
265+ _safeSort ( ) : XtSortBy < T > [ ] {
266+ const ret = store . sort ?store . sort ( ) :null ;
267+ if ( ( ret != null ) && ( ret . length > 0 ) ) {
268+ return ret ;
269+ }
270+ return [ ] ;
225271 }
226272 } )
227273 )
0 commit comments