import type { Field, FieldsSource, PatternsFieldType } from '@wix/bex-core'; import type { EditableColumn, ValidationRule } from './EditableTable/types'; import { FIELD_TYPE_TO_CELL_TYPE } from './EditableTable/fieldTypeToCellType'; // Types whose editable cell needs typeConfig the projection can't supply yet // (referenced collection, address shape). Until that lands, they render as a // read-only 'object' cell rather than a broken editor. const NEEDS_TYPE_CONFIG = new Set([ 'REFERENCE', 'MULTI_REFERENCE', 'ADDRESS', ]); function toValidationRules(field: Field): ValidationRule[] { const v = field.validation; if (!v) { return []; } const rules: ValidationRule[] = []; if (v.required) { rules.push({ type: 'required', message: `${field.displayName} is required`, }); } if (v.numberRange?.min != null) { rules.push({ type: 'min', value: v.numberRange.min, message: '' }); } if (v.numberRange?.max != null) { rules.push({ type: 'max', value: v.numberRange.max, message: '' }); } if (v.stringLengthRange?.minLength != null) { rules.push({ type: 'minLength', value: v.stringLengthRange.minLength, message: '', }); } if (v.stringLengthRange?.maxLength != null) { rules.push({ type: 'maxLength', value: v.stringLengthRange.maxLength, message: '', }); } return rules; } /** * Projects a FieldsSource's fields into EditableTable columns: a cell type by * field type, value read/write through the source, validation from the field, * and the flags the header reads for its disable rules. A cell is editable only * when the source can write it back (setCellValue) and the field isn't a system * field. */ export function buildEditableFieldColumns( source: FieldsSource, ): EditableColumn>[] { const canWrite = typeof source.setCellValue === 'function'; return source.fields.map((field) => { const id = source.columnIdForField(field); const cellType = NEEDS_TYPE_CONFIG.has(field.type) ? 'object' : FIELD_TYPE_TO_CELL_TYPE[field.type] ?? 'object'; const validation = toValidationRules(field); const editable = canWrite && cellType !== 'object' && !field.isSystem; return { id, cellType, field, title: field.displayName, name: field.displayName, isPrimary: field.isPrimary, isSystem: field.isSystem, hideable: true, sortable: field.capabilities?.sortable ?? false, editable, validation: validation.length ? validation : undefined, getValue: (item) => source.getCellValue(item, field), setValue: editable ? (item, value) => source.setCellValue!(item, field, value) as Record : undefined, } as EditableColumn>; }); }