Skip to content

Commit

Permalink
feat: add rules manager
Browse files Browse the repository at this point in the history
  • Loading branch information
cafadev committed Jun 4, 2023
1 parent 5ae692a commit 98a7ae9
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 20 deletions.
1 change: 1 addition & 0 deletions auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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']
Expand Down
9 changes: 9 additions & 0 deletions src/forms/axioma/typing/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export type Rule = (value?: any) => RawRuleResult

export interface RuleOptions {
processResult?: (rawResult: any) => RuleResult
preventErrorMessage?: boolean
}

export interface BaseRawField extends Record<string, any> {
Expand Down Expand Up @@ -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<string, unknown>) => void
getForeignKeyValues: (fields?: ObjectWithNormalizedFields) => void
resetFields: () => void
Expand All @@ -199,6 +207,7 @@ export interface FormManager {
switchToCreateMode: () => void
switchToUpdateMode: () => void
isFormValid: () => boolean
setRuleOptions(ruleOptions: RuleOptions): void
}

export interface Form<T, U> {
Expand Down
30 changes: 17 additions & 13 deletions src/forms/capabilities/fields/validate-field-rules.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
19 changes: 12 additions & 7 deletions src/forms/capabilities/manager/form.ts
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -11,16 +12,16 @@ const forms = new Map<symbol, FormMap>()
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 {
Expand Down Expand Up @@ -109,4 +110,8 @@ export class FormManagerHandler implements FormManager {
...options,
})
}

setRuleOptions(ruleOptions: RuleOptions = {}) {
this.ruleOptionsManager.setRuleOptions(ruleOptions)
}
}
26 changes: 26 additions & 0 deletions src/forms/capabilities/manager/rules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { RuleOptions, RuleOptionsManager } from '@/forms/axioma'

const ruleOptions = new Map<symbol, RuleOptions>()

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)
}
}

0 comments on commit 98a7ae9

Please sign in to comment.