import React, { useEffect, useState } from 'react'; import { UseFormRegister, useFieldArray, ArrayPath, useWatch, Path } from 'react-hook-form'; import { FieldValues } from 'react-hook-form/dist/types/fields'; import AuthProviderAPI from '../../api/auth-provider'; import { MappingFields, mappingType, ProvidableType } from '../../models/authentication-provider'; import { Control } from 'react-hook-form/dist/types/form'; import { FormSelect } from '../form/form-select'; import { FormInput } from '../form/form-input'; import { useTranslation } from 'react-i18next'; import { FabButton } from '../base/fab-button'; import { TypeMappingModal } from './type-mapping-modal'; import { useImmer } from 'use-immer'; import { Oauth2DataMappingForm } from './oauth2-data-mapping-form'; import { OpenidConnectDataMappingForm } from './openid-connect-data-mapping-form'; export interface DataMappingFormProps { register: UseFormRegister, control: Control, providerType: ProvidableType, } type selectModelFieldOption = { value: string, label: string }; /** * Partial form to define the mapping of the data between the API of the authentication provider and the application internals. */ export const DataMappingForm = ({ register, control, providerType }: DataMappingFormProps) => { const { t } = useTranslation('admin'); const [dataMapping, setDataMapping] = useState(null); const [isOpenTypeMappingModal, updateIsOpenTypeMappingModal] = useImmer>(new Map()); const { fields, append, remove } = useFieldArray({ control, name: 'auth_provider_mappings_attributes' as ArrayPath }); const output = useWatch({ name: 'auth_provider_mappings_attributes' as Path, control }); /** * Build the list of available models for the data mapping */ const buildModelOptions = (): Array => { if (!dataMapping) return []; return Object.keys(dataMapping).map(model => { return { label: model, value: model }; }) || []; }; /** * Build the list of fields of the current model for the data mapping */ const buildFieldOptions = (formData: Array, index: number): Array => { if (!dataMapping) return []; return dataMapping[getModel(formData, index)]?.map(field => { return { label: field[0], value: field[0] }; }) || []; }; /** * Return the name of the modal for the given index, in the current data-mapping form */ const getModel = (formData: Array, index: number): string => { return formData ? formData[index]?.local_model : undefined; }; /** * Return the name of the field for the given index, in the current data-mapping form */ const getField = (formData: Array, index: number): string => { return formData ? formData[index]?.local_field : undefined; }; /** * Return the type of data expected for the given index, in the current data-mapping form */ const getDataType = (formData: Array, index: number): mappingType => { const model = getModel(formData, index); const field = getField(formData, index); if (model && field && dataMapping) { return dataMapping[model]?.find(f => f[0] === field)?.[1]; } }; /** * Open/closes the "edit type mapping" modal dialog for the given mapping index */ const toggleTypeMappingModal = (index: number): () => void => { return () => { updateIsOpenTypeMappingModal(draft => draft.set(index, !draft.get(index))); }; }; // fetch the mapping data from the API on mount useEffect(() => { AuthProviderAPI.mappingFields().then((data) => { setDataMapping(data); }); }, []); return (

{t('app.admin.authentication.data_mapping_form.define_the_fields_mapping')}

} onClick={() => append({})}> {t('app.admin.authentication.data_mapping_form.add_a_match')}
{fields.map((item, index) => (
{providerType === 'OAuth2Provider' && } {providerType === 'OpenIdConnectProvider' && }
} onClick={toggleTypeMappingModal(index)} disabled={getField(output, index) === undefined} tooltip={t('app.admin.authentication.data_mapping_form.data_mapping')} /> } onClick={() => remove(index)} className="delete-button" />
))}
); };