diff --git a/projects/natural/src/lib/classes/abstract-list.ts b/projects/natural/src/lib/classes/abstract-list.ts index 757032c9..0014f9fc 100644 --- a/projects/natural/src/lib/classes/abstract-list.ts +++ b/projects/natural/src/lib/classes/abstract-list.ts @@ -569,7 +569,7 @@ export class NaturalAbstractList< } /** - * Delete multiple items at once + * Delete multiple items at once, and then refresh the list of items automatically */ protected bulkDelete(): Observable { const subject = new Subject(); @@ -581,12 +581,16 @@ export class NaturalAbstractList< // never call this method. const selection = this.selection.selected as {id: string}[]; - this.service.delete(selection).subscribe(() => { - this.selection.clear(); - this.alertService.info($localize`Supprimé`); - subject.next(); - subject.complete(); - }); + this.service + .delete(selection, { + refetchQueries: this.service.allQuery ? [this.service.allQuery] : [], + }) + .subscribe(() => { + this.selection.clear(); + this.alertService.info($localize`Supprimé`); + subject.next(); + subject.complete(); + }); } }); diff --git a/projects/natural/src/lib/services/abstract-model.service.spec.ts b/projects/natural/src/lib/services/abstract-model.service.spec.ts index ef26162a..2cac7c7a 100644 --- a/projects/natural/src/lib/services/abstract-model.service.spec.ts +++ b/projects/natural/src/lib/services/abstract-model.service.spec.ts @@ -8,7 +8,6 @@ import {type Literal} from '../types/types'; import {NullService} from '../testing/null.service'; import {Apollo} from 'apollo-angular'; import {takeWhile} from 'rxjs/operators'; -import {type ObservableQuery} from '@apollo/client'; const observableError = 'Cannot use Observable as variables. Instead you should use .subscribe() to call the method with a real value'; @@ -27,41 +26,6 @@ describe('NaturalAbstractModelService', () => { service = TestBed.inject(PostService); }); - it('should be delay deleted resolving', fakeAsync(() => { - const apollo = TestBed.inject(Apollo); - - let resolveMyPromise: (value: ObservableQuery.Result[]) => void; - apollo.client.refetchObservableQueries = () => - new Promise[]>(resolve => { - resolveMyPromise = resolve; - }); - - let resolved = false; - let completed = false; - service.delete([{id: '123'}]).subscribe({ - next: () => { - resolved = true; - }, - complete: () => { - completed = true; - }, - }); - - expect(resolved).toBeFalse(); - expect(completed).toBeFalse(); - - tick(2000); - - expect(resolved).toBeFalse(); - expect(completed).toBeFalse(); - - resolveMyPromise!([]); - tick(2000); - - expect(resolved).toBeTrue(); - expect(completed).toBeTrue(); - })); - it('should be created', () => { expect(service).toBeTruthy(); }); diff --git a/projects/natural/src/lib/services/abstract-model.service.ts b/projects/natural/src/lib/services/abstract-model.service.ts index 48f38963..8a315b41 100644 --- a/projects/natural/src/lib/services/abstract-model.service.ts +++ b/projects/natural/src/lib/services/abstract-model.service.ts @@ -1,5 +1,11 @@ import {Apollo, gql, onlyCompleteData} from 'apollo-angular'; -import {type ApolloLink, NetworkStatus, type ObservableQuery, type WatchQueryFetchPolicy} from '@apollo/client'; +import { + type ApolloLink, + NetworkStatus, + type ObservableQuery, + type OperationVariables, + type WatchQueryFetchPolicy, +} from '@apollo/client'; import { type AbstractControl, type AsyncValidatorFn, @@ -10,7 +16,7 @@ import { import {type DocumentNode} from 'graphql'; import {merge, pick} from 'es-toolkit'; import {defaults} from 'es-toolkit/compat'; -import {catchError, combineLatest, EMPTY, first, from, Observable, of, type OperatorFunction} from 'rxjs'; +import {catchError, combineLatest, EMPTY, first, Observable, of, type OperatorFunction} from 'rxjs'; import {debounceTime, filter, map, shareReplay, startWith, switchMap, takeWhile, tap} from 'rxjs/operators'; import {NaturalQueryVariablesManager, type QueryVariables} from '../classes/query-variable-manager'; import {type Literal} from '../types/types'; @@ -32,6 +38,11 @@ export type FormControls = Record; export type WithId = {id: string} & T; +export type MutateOptionsWithoutVariables = Omit< + Apollo.MutateOptions, + 'mutation' | 'variables' +>; + export abstract class NaturalAbstractModelService< Tone, Vone extends {id: string}, @@ -68,7 +79,7 @@ export abstract class NaturalAbstractModelService< public constructor( protected readonly name: string, protected readonly oneQuery: DocumentNode | null, - protected readonly allQuery: DocumentNode | null, + public readonly allQuery: DocumentNode | null, protected readonly createMutation: DocumentNode | null, protected readonly updateMutation: DocumentNode | null, protected readonly deleteMutation: DocumentNode | null, @@ -362,9 +373,12 @@ export abstract class NaturalAbstractModelService< } /** - * Create an object in DB and then refetch the list of objects + * Create an object in DB */ - public create(object: Vcreate['input']): Observable { + public create( + object: Vcreate['input'], + options: MutateOptionsWithoutVariables = {}, + ): Observable { this.throwIfObservable(object); this.throwIfNotQuery(this.createMutation); @@ -375,15 +389,11 @@ export abstract class NaturalAbstractModelService< return this.apollo .mutate({ + ...(options as MutateOptionsWithoutVariables), mutation: this.createMutation, variables: variables, }) - .pipe( - map(result => { - this.apollo.client.refetchObservableQueries(); - return this.mapCreation(result); - }), - ); + .pipe(map(result => this.mapCreation(result))); } /** @@ -430,7 +440,10 @@ export abstract class NaturalAbstractModelService< /** * Delete objects and then refetch the list of objects */ - public delete(objects: {id: string}[]): Observable { + public delete( + objects: {id: string}[], + options: MutateOptionsWithoutVariables = {}, + ): Observable { this.throwIfObservable(objects); this.throwIfNotQuery(this.deleteMutation); @@ -449,17 +462,11 @@ export abstract class NaturalAbstractModelService< return this.apollo .mutate({ + ...(options as MutateOptionsWithoutVariables), mutation: this.deleteMutation, variables: variables, }) - .pipe( - // Delay the observable until Apollo refetch is completed - switchMap(result => { - const mappedResult = this.mapDelete(result); - - return from(this.apollo.client.refetchObservableQueries()).pipe(map(() => mappedResult)); - }), - ); + .pipe(map(result => this.mapDelete(result))); } /**