import type { FieldsSource, Field, CustomField, CustomFieldType, DataExtensionState, ExtendedFields, ReportBI, } from '@wix/bex-core'; import { prefixFieldWithNamespace } from '../../state/simplifyExtendedColumns'; import { dataExtensionFieldManagement, toPatternsFieldType, } from './dataExtensionFieldManagement'; import { dataExtensionArchive } from './dataExtensionArchive'; const FILTERABLE_TYPES: CustomFieldType[] = [ 'shortText', 'longText', 'url', 'date', 'dateTime', 'integer', 'decimal', 'checkbox', ]; export interface DataExtensionFieldsSourceParams { dataExtension: DataExtensionState; reportBi: ReportBI; toExtendedFields?: (row: any) => ExtendedFields | undefined | null; } export const dataExtensionFieldsSourceFrom = ( params: DataExtensionFieldsSourceParams, ): FieldsSource => { const d = params.dataExtension; const toField = (cf: CustomField): Field => ({ id: cf.id, displayName: cf.label ?? cf.id, type: toPatternsFieldType(cf.type), isPii: cf.isPii, capabilities: { sortable: cf.filterable ?? false, supportedQueryOperators: [], }, }); const customFieldFor = (id: string): CustomField | undefined => d.availableCustomFields.find((f) => f.id === id); // Field carries no namespace; recover it from the source CustomField so the // namespace prefix stays inside the DataExtension adapter. const fieldPath = (field: Field): string => prefixFieldWithNamespace( field.id, customFieldFor(field.id)?.namespace ?? '', ); const source: FieldsSource = { load: async () => { d.container.initTask.runOnce(); await Promise.all([ d.container.initTask.status.promise, d.fetchSchemas(), ]); }, get fields() { return d.availableCustomFields.map(toField); }, get filterableFields() { if (!d.filterable) { return []; } return d.availableCustomFields .filter((f) => f.filterable && FILTERABLE_TYPES.includes(f.type)) .map(toField); }, get manageableFields() { return d.availableUserCustomFields.map(toField); }, columnIdForField: fieldPath, queryFieldId: fieldPath, getCellValue: (row, field) => params.toExtendedFields?.(row)?.namespaces?.[ customFieldFor(field.id)?.namespace ?? '' ]?.[field.id], fieldManagement: dataExtensionFieldManagement({ dataExtension: d, reportBi: params.reportBi, }), groups: { get all() { return d.allNamespaces; }, fieldsForGroup: (group) => d.availableCustomFields .filter((f) => f.namespace === group) .map(toField), }, }; // Always provide archive — NOT gated on enableArchive. It backs the remove // confirm modal, which must open whether or not archive is enabled (the modal // shows "cannot be restored" when it isn't). The archived-items panel stays // hidden when archive is off via `shouldDisplayArchive` (= enableArchive && …). source.archive = dataExtensionArchive({ dataExtension: d, reportBi: params.reportBi, }); return source; };