diff --git a/projects/natural/src/lib/classes/abstract-detail.ts b/projects/natural/src/lib/classes/abstract-detail.ts index 492a21a0..90e4fcff 100644 --- a/projects/natural/src/lib/classes/abstract-detail.ts +++ b/projects/natural/src/lib/classes/abstract-detail.ts @@ -36,7 +36,10 @@ export class NaturalAbstractDetail): AsyncValidatorFn { + + const validator = (control: AbstractControl): Observable => { + + const condition = {}; + + if (control.value) { + + condition[fieldName] = {equal: {value: control.value}}; + const variables: any = { + pagination: {pageIndex: 0, pageSize: 0}, + filter: {groups: [{conditions: [condition]}]}, + }; + + const qvm = new NaturalQueryVariablesManager(); + qvm.set('variables', variables); + + return modelService.count(qvm).pipe( + map((count: number) => { + return count > 0 ? {duplicateValue: count} : null; + }), + ); + } + + return of(null); + }; + return validator; + } +} 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 9a21e773..549775da 100644 --- a/projects/natural/src/lib/services/abstract-model.service.spec.ts +++ b/projects/natural/src/lib/services/abstract-model.service.spec.ts @@ -148,6 +148,23 @@ export abstract class AbstractModelServiceSpec { expect(Object.keys(object).length).toBeGreaterThan(keysAfterCreation); // should show created + updated objects merged })), ); + + it('should count existing values', + fakeAsync(inject([serviceClass], (service: ModelService) => { + const qvm = new NaturalQueryVariablesManager(); + const variables: any = { + pagination: {pageIndex: 0, pageSize: 0}, + filter: {groups: [{conditions: [{slug: 'test string'}]}]}, + }; + qvm.set('variables', variables); + expect(() => service.count(qvm).subscribe()).toEqual(1); + + variables['filter']['groups'][0]['conditions'][0]['slug'] = 'other string'; + qvm.set('variables', variables); + expect(() => service.count(qvm).subscribe()).toEqual(0); + + })), + ); } private static expectNotConfiguredOrEqual(expectSuccess: boolean, diff --git a/projects/natural/src/lib/services/abstract-model.service.ts b/projects/natural/src/lib/services/abstract-model.service.ts index 8fe3f8c9..a5827e41 100644 --- a/projects/natural/src/lib/services/abstract-model.service.ts +++ b/projects/natural/src/lib/services/abstract-model.service.ts @@ -1,4 +1,4 @@ -import { ValidatorFn } from '@angular/forms'; +import gql from 'graphql-tag'; import { Apollo } from 'apollo-angular'; import { NetworkStatus } from 'apollo-client'; import { FetchResult } from 'apollo-link'; @@ -10,11 +10,16 @@ import { NaturalFormControl } from '../classes/form-control'; import { NaturalQueryVariablesManager } from '../classes/query-variable-manager'; import { NaturalUtility } from '../classes/utility'; import { Literal } from '../types/types'; +import {AsyncValidatorFn, ValidatorFn} from '@angular/forms'; export interface FormValidators { [key: string]: ValidatorFn[]; } +export interface FormAsyncValidators { + [key: string]: AsyncValidatorFn[]; +} + export interface VariablesWithInput { input: Literal; } @@ -67,6 +72,13 @@ export abstract class NaturalAbstractModelService): Observable { + const plural = NaturalUtility.makePlural(this.name); + let query = 'query Count' + NaturalUtility.upperCaseFirstLetter(plural); + query += '($filter: ' + NaturalUtility.upperCaseFirstLetter(this.name) + 'Filter) {'; + query += plural + '(filter: $filter, pagination: {pageSize: 0}) { length } }'; + query = gql(query); + return this.apollo.query({ + query: query, + variables: queryVariablesManager.variables.value, + }).pipe( + map((result) => { + return result.data[plural].length as number; + }), + ); + } + /** * Return empty object with some default values from server perspective * diff --git a/projects/natural/src/lib/testing/mock-apollo.provider.ts b/projects/natural/src/lib/testing/mock-apollo.provider.ts index fbe6b5d0..dde91738 100644 --- a/projects/natural/src/lib/testing/mock-apollo.provider.ts +++ b/projects/natural/src/lib/testing/mock-apollo.provider.ts @@ -33,6 +33,7 @@ const typeDefs = ` type Post { id: ID! + slug: String blog: Blog } diff --git a/projects/natural/src/public-api.ts b/projects/natural/src/public-api.ts index 045f6ff0..6333dbdb 100644 --- a/projects/natural/src/public-api.ts +++ b/projects/natural/src/public-api.ts @@ -12,6 +12,7 @@ export * from './lib/classes/data-source'; export * from './lib/classes/form-control'; export * from './lib/classes/query-variable-manager'; export * from './lib/classes/utility'; +export * from './lib/classes/validators'; export * from './lib/services/abstract-model.service'; export * from './lib/services/enum.service';