Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 34x 28x 1x 34x 34x 42x 9x 33x 33x 33x 93x 45x 48x 48x 33x 33x 15x | /** * Copyright (c) Siemens 2016 - 2025 * SPDX-License-Identifier: MIT */ import { inject, Injectable } from '@angular/core'; import { ValidationErrors } from '@angular/forms'; import { t } from '@siemens/element-translate-ng/translate'; import { SiFormError } from './si-form-item/si-form-item.component'; import { SiFormValidationErrorMapper } from './si-form-validation-error.model'; /** * Creates the map of default error resolver. * This is a function as $localize requires an injection context. * * @internal */ export const buildDefaults = (): SiFormValidationErrorMapper => ({ min: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.MIN:The value is too small`), max: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.MAX:The value is too large.`), required: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.REQUIRED:A value is required.`), requiredTrue: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.REQUIRED_TRUE:The value should be true.` ), email: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.EMAIL:The email is not valid.`), minlength: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.MIN_LENGTH:The minimum number of characters is not met.` ), maxlength: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.MAX_LENGTH:A maximum number of characters is exceeded.` ), ipv4Address: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.IPV4:Invalid IPv4 address.`), ipv6Address: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.IPV6:Invalid IPv6 address.`), pattern: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.PATTERN:The value does not match the predefined pattern.` ), numberFormat: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.NUMBER_FORMAT:The value is not a valid number.` ), dateFormat: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.DATE_FORMAT:Invalid date format.`), maxDate: t( () => $localize`:@@SI_FORM_CONTAINER.ERROR.MAX_DATE:The date is too far in the future.` ), minDate: t(() => $localize`:@@SI_FORM_CONTAINER.ERROR.MIN_DATE:The date is too far in the past.`) }); /** * A service to resolve the validation error of an Angular control to a message or translation key. * * It can be provided using {@link provideFormValidationErrorMapper}. * If not provided, there will be a default instance in the root injector using only the default keys. * * There can be multiple instances to support providing in a lazy loaded module. * If the service cannot find a message, it will try to resolve it using a parent service if available. * * @internal */ @Injectable({ providedIn: 'root', useFactory: () => new SiFormValidationErrorService(buildDefaults()) }) export class SiFormValidationErrorService { private readonly parent = inject(SiFormValidationErrorService, { optional: true, skipSelf: true }); // eslint-disable-next-line @angular-eslint/prefer-inject constructor(private errorMapper: SiFormValidationErrorMapper) {} /** * Resolves the provided form errors to a list of {@link SiFormError}. * To resolution order is: * 1. componentMapper * 2. containerMapper using the controlName * 3. containerMapper without controlName * 4. errorMapper of the service using the controlName * 5. errorMapper of the service * 6: parent service */ resolveErrors( controlName: string | number | null | undefined, errors: ValidationErrors | null, componentMapper?: SiFormValidationErrorMapper, containerMapper?: SiFormValidationErrorMapper ): SiFormError[] { if (!errors) { return []; } /* * Converts the angular error object (like: {required: true, minLength: {actualLength: 1, requiredLength: 3}}) * to SiFormError[]. * Therefore, the error key is look up in the error mappers. * If it can be resolved, the error will be printed using the resolved text. */ return Object.entries(errors).map(([key, params]) => this.resolveError(key, controlName, params, componentMapper, containerMapper) ); } private resolveError( key: string, controlName: string | number | null | undefined, params: any, componentMapper?: SiFormValidationErrorMapper, containerMapper?: SiFormValidationErrorMapper ): SiFormError { return ( this.resolveMessage(key, controlName, params, componentMapper) ?? this.resolveMessage(key, controlName, params, containerMapper) ?? this.resolveMessage(key, controlName, params, this.errorMapper) ?? this.parent?.resolveError(key, controlName, params) ?? { key, params } ); } private resolveMessage( key: string, controlName: string | number | null | undefined, params: any, mapper?: SiFormValidationErrorMapper ): SiFormError | undefined { if (!mapper) { return undefined; } const resolver = mapper[`${controlName}.${key}`] ?? mapper[key]; if (resolver) { const message = typeof resolver === 'function' ? resolver(params) : resolver; return message ? { key, message, params } : undefined; } return undefined; } } |