- number-поля теперь рендерятся как text + inputMode=numeric, чтобы браузер не округлял значения через input type=number - пробелы при вставке в number-поля удаляются - бэкенд нормализует значения number-полей в строку перед сохранением - добавлен хелпер normalizeFieldValueForStorage Closes: искажение расчётного счёта и других длинных числовых полей
73 lines
2.1 KiB
TypeScript
73 lines
2.1 KiB
TypeScript
/**
|
|
* Проверка условной неизменности полей формы.
|
|
*/
|
|
|
|
import { isFieldImmutable } from "@shared/field-conditions";
|
|
import { buildFieldConditionContext } from "./field-condition-context";
|
|
|
|
export interface ValidateImmutableFieldsOptions {
|
|
task: { currentStatusId?: number | null; formId?: number; [key: string]: any };
|
|
formFields: Array<{
|
|
id: number;
|
|
code: string;
|
|
name: string;
|
|
type?: string;
|
|
options?: unknown;
|
|
immutableRules?: any;
|
|
autoProlongationLabel?: string | null;
|
|
}>;
|
|
changedFieldIds: number[];
|
|
existingFieldValues?: Array<{ fieldId: number; value: unknown }>;
|
|
organizationId: number;
|
|
storage: any;
|
|
isCreation?: boolean;
|
|
statuses?: Array<{ id: number; position: number; isFinal?: boolean | null }>;
|
|
users?: Array<{ id: number; firstName?: string | null; middleName?: string | null; lastName?: string | null; email?: string }>;
|
|
roles?: Array<{ id: number; name?: string }>;
|
|
}
|
|
|
|
export async function validateImmutableFields(
|
|
options: ValidateImmutableFieldsOptions
|
|
): Promise<string[]> {
|
|
const {
|
|
task,
|
|
formFields,
|
|
changedFieldIds,
|
|
existingFieldValues,
|
|
organizationId,
|
|
storage,
|
|
statuses: providedStatuses,
|
|
users: providedUsers,
|
|
roles: providedRoles,
|
|
} = options;
|
|
|
|
const fieldsWithRules = formFields.filter(
|
|
(f) => f.immutableRules && f.immutableRules.enabled && changedFieldIds.includes(f.id)
|
|
);
|
|
if (fieldsWithRules.length === 0) return [];
|
|
|
|
const ctxResult = await buildFieldConditionContext({
|
|
task,
|
|
formFields,
|
|
organizationId,
|
|
storage,
|
|
isCreation: options.isCreation,
|
|
statuses: providedStatuses,
|
|
existingFieldValues,
|
|
users: providedUsers,
|
|
roles: providedRoles,
|
|
});
|
|
|
|
const { fields, fieldValues, ...context } = ctxResult;
|
|
|
|
const errors: string[] = [];
|
|
for (const field of fieldsWithRules) {
|
|
const immutable = isFieldImmutable(field as any, task, fieldValues, fields, context);
|
|
if (immutable) {
|
|
errors.push(`Поле «${field.name}» не может быть изменено в текущем состоянии`);
|
|
}
|
|
}
|
|
|
|
return errors;
|
|
}
|