import { action, computed, makeObservable, observable } from 'mobx'; import { CustomFieldsFormState } from './CustomFieldsFormState'; import { CustomFieldsWidgetState } from './CustomFieldsWidgetState'; import orderBy from 'lodash/orderBy'; import { DataExtensionField } from '@wix/bex-core'; export interface CustomFieldsAllNamespacesFormStateParams { customFieldsWidgetState: CustomFieldsWidgetState; } export class CustomFieldsAllNamespacesFormState { readonly _customFieldsWidgetState; readonly namespacesFormsMap = observable.map( [], { deep: false, }, ); constructor(params: CustomFieldsAllNamespacesFormStateParams) { this._customFieldsWidgetState = params.customFieldsWidgetState; makeObservable(this, { namespacesForms: computed, addFormIfAbsent: action, validate: action, isDirty: computed, schemasSections: computed, tpaFieldsExist: computed, }); } get schemasSections() { const { _customFieldsWidgetState: { dataExtension: { _dataExtensionSchemas }, _userFieldsNamespace, }, } = this; const schemasWithEditableProps = _dataExtensionSchemas.filter( (schema) => schema.jsonSchema?.properties && Object.keys(schema.jsonSchema.properties).length > 0 && (schema.namespace === _userFieldsNamespace || Object.values( schema.jsonSchema.properties as Record, ).some( (prop) => prop['x-wix-permissions']?.write?.includes('users') && prop['x-wix-permissions']?.read?.includes('users'), )), ); return orderBy( schemasWithEditableProps, [ (s) => (s.namespace === _userFieldsNamespace ? 1 : 0), (s) => s.createdDate, ], ['desc', 'desc'], ); } get tpaFieldsExist() { const { schemasSections, _customFieldsWidgetState: { _userFieldsNamespace }, } = this; return schemasSections.some( (schema) => schema.namespace !== _userFieldsNamespace, ); } getNamespaceFormSchemaAndData(namespace: string) { const { _customFieldsWidgetState: state } = this; const { schema, fields } = state.dataExtension.getSchemaAndFieldsByNamespace(namespace); return { fields, schema, extendedFieldsDataMap: state._extendedFields?.namespaces?.[namespace], }; } get namespacesForms() { return Array.from(this.namespacesFormsMap.values()); } addFormIfAbsent(form: CustomFieldsFormState) { const { namespacesFormsMap } = this; const maybeForm = namespacesFormsMap.get(form._namespace) ?? form; namespacesFormsMap.set(form._namespace, maybeForm); return maybeForm; } validate() { const { namespacesFormsMap, _customFieldsWidgetState: { _userFieldsNamespace }, } = this; const resultsMap = new Map( Array.from(namespacesFormsMap.values()).map((form) => [ form._namespace, form.validate(), ]), ); const results = Array.from(resultsMap.values()); const extendedFields = Object.fromEntries( Array.from(resultsMap.entries()).map(([namespace, result]) => [ namespace, result.extendedFields, ]), ); return { isValid: results.every((result) => result.isValid), extendedFields: { namespaces: { [_userFieldsNamespace]: {}, ...extendedFields, }, }, }; } get isDirty() { const { namespacesForms } = this; return namespacesForms.some((form) => form.isDirty); } }