diff --git a/CHANGELOG.md b/CHANGELOG.md index ce6bf2ca3..6b5156a89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,7 @@ - Fix a bug: unable to generate the secret key base during the setup - Fix a bug: error message during the setup: the input device is not a TTY - Fix a bug: when Fab-manager was installed as non-root user, unable to compile the assets during the upgrade +- Fix a bug: unable to remove an SSO data mapping field once saved - [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/set-docker-user.sh | bash` ## v5.4.4 2022 June 8 diff --git a/app/frontend/src/javascript/components/authentication-provider/data-mapping-form.tsx b/app/frontend/src/javascript/components/authentication-provider/data-mapping-form.tsx index 1b2cd034f..b139a1194 100644 --- a/app/frontend/src/javascript/components/authentication-provider/data-mapping-form.tsx +++ b/app/frontend/src/javascript/components/authentication-provider/data-mapping-form.tsx @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react'; -import { UseFormRegister, useFieldArray, ArrayPath, useWatch, Path } from 'react-hook-form'; +import { UseFormRegister, useFieldArray, ArrayPath, useWatch, Path, FieldPathValue } from 'react-hook-form'; import { FieldValues } from 'react-hook-form/dist/types/fields'; import AuthProviderAPI from '../../api/auth-provider'; import { AuthenticationProviderMapping, MappingFields, mappingType, ProvidableType } from '../../models/authentication-provider'; -import { Control, UseFormSetValue } from 'react-hook-form/dist/types/form'; +import { Control, UnpackNestedValue, UseFormSetValue } from 'react-hook-form/dist/types/form'; import { FormSelect } from '../form/form-select'; import { FormInput } from '../form/form-input'; import { useTranslation } from 'react-i18next'; @@ -96,6 +96,31 @@ export const DataMappingForm = { + if (currentFormValues[index].id) { + setValue( + `auth_provider_mappings_attributes.${index}._destroy` as Path, + true as UnpackNestedValue>> + ); + } else { + remove(index); + } + }; + + /** + * Return a className based on the current mapping-item status + */ + const itemStatus = (index: number): string => { + if (currentFormValues[index]?.id) { + if (currentFormValues[index]._destroy) return 'destroyed-item'; + return 'saved-item'; + } + return 'new-item'; + }; + // fetch the mapping data from the API on mount useEffect(() => { AuthProviderAPI.mappingFields().then((data) => { @@ -114,7 +139,7 @@ export const DataMappingForm = {fields.map((item, index) => ( -
+
@@ -141,7 +166,7 @@ export const DataMappingForm = - } onClick={() => remove(index)} className="delete-button" /> + } onClick={() => removeMapping(index)} className="delete-button" /> ({ const model = currentFormValues[index]?.local_model; const field = currentFormValues[index]?.local_field; const configuration = standardConfiguration[`${model}.${field}`]; - setValue( - `auth_provider_mappings_attributes.${index}.api_field` as Path, - configuration.api_field as UnpackNestedValue>> - ); - if (configuration.transformation) { - Object.keys(configuration.transformation).forEach((key) => { - setValue( - `auth_provider_mappings_attributes.${index}.transformation.${key}` as Path, - configuration.transformation[key] as UnpackNestedValue>> - ); - }); + if (configuration) { + setValue( + `auth_provider_mappings_attributes.${index}.api_field` as Path, + configuration.api_field as UnpackNestedValue>> + ); + if (configuration.transformation) { + Object.keys(configuration.transformation).forEach((key) => { + setValue( + `auth_provider_mappings_attributes.${index}.transformation.${key}` as Path, + configuration.transformation[key] as UnpackNestedValue>> + ); + }); + } } }; diff --git a/app/frontend/src/javascript/models/authentication-provider.ts b/app/frontend/src/javascript/models/authentication-provider.ts index bf834867a..40ed22c4a 100644 --- a/app/frontend/src/javascript/models/authentication-provider.ts +++ b/app/frontend/src/javascript/models/authentication-provider.ts @@ -14,6 +14,7 @@ export type mappingType = 'string' | 'text' | 'date' | 'integer' | 'boolean'; export interface AuthenticationProviderMapping { id?: number, + _destroy?: boolean, local_model: 'user' | 'profile', local_field: string, api_field: string, diff --git a/app/frontend/src/stylesheets/modules/authentication-provider/array-mapping-form.scss b/app/frontend/src/stylesheets/modules/authentication-provider/array-mapping-form.scss index 3779b8e0a..263d0a50b 100644 --- a/app/frontend/src/stylesheets/modules/authentication-provider/array-mapping-form.scss +++ b/app/frontend/src/stylesheets/modules/authentication-provider/array-mapping-form.scss @@ -24,5 +24,13 @@ color: white; } } + + &.destroyed-item { + display: none; + } + + &.new-item { + background-color: var(--information-lightest); + } } }