diff --git a/auto-imports.d.ts b/auto-imports.d.ts index e7aee4c..d97403a 100644 --- a/auto-imports.d.ts +++ b/auto-imports.d.ts @@ -28,6 +28,7 @@ declare global { const RequestUpdate: typeof import('./src/http/capabilities/request-update')['RequestUpdate'] const ResetFields: typeof import('./src/forms/capabilities/fields/reset-fields')['ResetFields'] const ResponseManagerHandler: typeof import('./src/forms/capabilities/manager/response')['ResponseManagerHandler'] + const RuleOptionsManagerHandler: typeof import('./src/forms/capabilities/manager/rules')['RuleOptionsManagerHandler'] const TableManagerHandler: typeof import('./src/tables/capabilities/manager/table')['TableManagerHandler'] const Url: typeof import('./src/http/axioma/value-objects/url')['Url'] const ValidateFieldRules: typeof import('./src/forms/capabilities/fields/validate-field-rules')['ValidateFieldRules'] diff --git a/src/forms/axioma/typing/form.ts b/src/forms/axioma/typing/form.ts index ecf67b0..6143c95 100644 --- a/src/forms/axioma/typing/form.ts +++ b/src/forms/axioma/typing/form.ts @@ -20,6 +20,7 @@ export type Rule = (value?: any) => RawRuleResult export interface RuleOptions { processResult?: (rawResult: any) => RuleResult + preventErrorMessage?: boolean } export interface BaseRawField extends Record { @@ -185,9 +186,16 @@ export interface NotificationManager { removeNotificationHandlers: () => void } +export interface RuleOptionsManager { + setRuleOptions(ruleOptions: RuleOptions): void + getRuleOptions(): RuleOptions + removeRuleOptions(): void +} + export interface FormManager { readonly responseManager: ResponseManager readonly notificationManager: NotificationManager + readonly ruleOptionsManager: RuleOptionsManager fillWithRecordValues: (record: Record) => void getForeignKeyValues: (fields?: ObjectWithNormalizedFields) => void resetFields: () => void @@ -199,6 +207,7 @@ export interface FormManager { switchToCreateMode: () => void switchToUpdateMode: () => void isFormValid: () => boolean + setRuleOptions(ruleOptions: RuleOptions): void } export interface Form { diff --git a/src/forms/capabilities/fields/validate-field-rules.ts b/src/forms/capabilities/fields/validate-field-rules.ts index bd0f5b9..2f23600 100644 --- a/src/forms/capabilities/fields/validate-field-rules.ts +++ b/src/forms/capabilities/fields/validate-field-rules.ts @@ -1,34 +1,38 @@ import type { NormalizedField, RuleOptions, RuleResult } from '@/forms/axioma' export class ValidateFieldRules { - private setPossibleErrors(field: NormalizedField, result: RuleResult) { - if (result === true) + private setPossibleErrors(field: NormalizedField, result: RuleResult, options?: RuleOptions) { + if (result === true || options?.preventErrorMessage) return field.errors = [result] } + private isValidReturn(result: unknown, errorMessage: string): RuleResult { + if (typeof result === 'string' || (typeof result === 'boolean' && result === true)) + return result + + throw new Error(errorMessage) + } + execute(field: NormalizedField, options?: RuleOptions): RuleResult { if (!field.rules) return true + const errorMessage = `Unable to validate the field ${field.name}, rules function needs to return string or true. Otherwise you will need to process the initial return` + let result: RuleResult const rawResult = field.rules(field.modelValue) if (options?.processResult) { - const result = options.processResult(rawResult) - this.setPossibleErrors(field, result) + result = options.processResult(rawResult) + result = this.isValidReturn(result, errorMessage) + this.setPossibleErrors(field, result, options) return result } - if (typeof rawResult === 'string' || (typeof rawResult === 'boolean' && rawResult === true)) { - this.setPossibleErrors(field, rawResult) - return rawResult - } - - throw new Error( - `Unable to validate the field ${field.name}, rules function needs to return string or true. - Otherwise you will need to process the initial return`, - ) + result = this.isValidReturn(rawResult, errorMessage) + this.setPossibleErrors(field, result, options) + return result } } diff --git a/src/forms/capabilities/manager/form.ts b/src/forms/capabilities/manager/form.ts index bbe3836..ac7e4d3 100644 --- a/src/forms/capabilities/manager/form.ts +++ b/src/forms/capabilities/manager/form.ts @@ -1,8 +1,9 @@ import { FillWithRecordValues, GenerateFormData, HandleErrors, ResetFields, ValidateForm } from '../fields' import { ResponseManagerHandler } from './response' import { NotificationManagerHandler } from './notification' +import { RuleOptionsManagerHandler } from './rules' import { ValidateFieldRules } from '@/forms/capabilities' -import type { FieldErrors, FormManager, FormMap, NotificationManager, ObjectWithNormalizedFields, ResponseManager, RuleOptions } from '@/forms/axioma' +import type { FieldErrors, FormManager, FormMap, NotificationManager, ObjectWithNormalizedFields, ResponseManager, RuleOptions, RuleOptionsManager } from '@/forms/axioma' import { FormModes, NotificationType } from '@/forms/axioma' import { GetForeignKeyValues } from '@/http/axioma' @@ -11,16 +12,16 @@ const forms = new Map() export class FormManagerHandler implements FormManager { readonly responseManager: ResponseManager readonly notificationManager: NotificationManager + readonly ruleOptionsManager: RuleOptionsManager - private ruleOptions?: RuleOptions = {} - - constructor(private id: symbol, options?: { ruleOptions?: RuleOptions }) { + constructor(private id: symbol) { this.responseManager = new ResponseManagerHandler(id) this.notificationManager = new NotificationManagerHandler(id) + this.ruleOptionsManager = new RuleOptionsManagerHandler(id) + } - const { ruleOptions = {} } = options || {} - - this.ruleOptions = ruleOptions + get ruleOptions(): RuleOptions { + return this.ruleOptionsManager.getRuleOptions() } getForm(): FormMap { @@ -109,4 +110,8 @@ export class FormManagerHandler implements FormManager { ...options, }) } + + setRuleOptions(ruleOptions: RuleOptions = {}) { + this.ruleOptionsManager.setRuleOptions(ruleOptions) + } } diff --git a/src/forms/capabilities/manager/rules.ts b/src/forms/capabilities/manager/rules.ts new file mode 100644 index 0000000..c5182e3 --- /dev/null +++ b/src/forms/capabilities/manager/rules.ts @@ -0,0 +1,26 @@ +import type { RuleOptions, RuleOptionsManager } from '@/forms/axioma' + +const ruleOptions = new Map() + +export class RuleOptionsManagerHandler implements RuleOptionsManager { + constructor(private id: symbol) {} + + private getRuleOptionsFromMap() { + if (!ruleOptions.get(this.id)) + ruleOptions.set(this.id, {}) + + return ruleOptions.get(this.id)! + } + + setRuleOptions(newRuleOptions: RuleOptions) { + Object.assign(this.getRuleOptionsFromMap(), newRuleOptions) + } + + getRuleOptions(): RuleOptions { + return this.getRuleOptionsFromMap() + } + + removeRuleOptions() { + ruleOptions.delete(this.id) + } +}