mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-28 22:54:18 +01:00
(bug) unable to remove an SSO data mapping field once saved
This commit is contained in:
parent
2d80600e97
commit
c1246092ed
CHANGELOG.md
app/frontend/src
javascript
components/authentication-provider
models
stylesheets/modules/authentication-provider
@ -24,6 +24,7 @@
|
|||||||
- Fix a bug: unable to generate the secret key base during the setup
|
- 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: 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: 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`
|
- [TODO DEPLOY] `\curl -sSL https://raw.githubusercontent.com/sleede/fab-manager/master/scripts/set-docker-user.sh | bash`
|
||||||
|
|
||||||
## v5.4.4 2022 June 8
|
## v5.4.4 2022 June 8
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
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 { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||||
import AuthProviderAPI from '../../api/auth-provider';
|
import AuthProviderAPI from '../../api/auth-provider';
|
||||||
import { AuthenticationProviderMapping, MappingFields, mappingType, ProvidableType } from '../../models/authentication-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 { FormSelect } from '../form/form-select';
|
||||||
import { FormInput } from '../form/form-input';
|
import { FormInput } from '../form/form-input';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@ -96,6 +96,31 @@ export const DataMappingForm = <TFieldValues extends FieldValues, TContext exten
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the data whom index is provided: mark it as "to destroy" or simply remove it if it was unsaved
|
||||||
|
*/
|
||||||
|
const removeMapping = (index: number): void => {
|
||||||
|
if (currentFormValues[index].id) {
|
||||||
|
setValue(
|
||||||
|
`auth_provider_mappings_attributes.${index}._destroy` as Path<TFieldValues>,
|
||||||
|
true as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
||||||
|
);
|
||||||
|
} 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
|
// fetch the mapping data from the API on mount
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
AuthProviderAPI.mappingFields().then((data) => {
|
AuthProviderAPI.mappingFields().then((data) => {
|
||||||
@ -114,7 +139,7 @@ export const DataMappingForm = <TFieldValues extends FieldValues, TContext exten
|
|||||||
</FabButton>
|
</FabButton>
|
||||||
</div>
|
</div>
|
||||||
{fields.map((item, index) => (
|
{fields.map((item, index) => (
|
||||||
<div key={item.id} className="mapping-item">
|
<div key={item.id} className={`mapping-item ${itemStatus(index)}`}>
|
||||||
<div className="inputs">
|
<div className="inputs">
|
||||||
<FormInput id={`auth_provider_mappings_attributes.${index}.id`} register={register} type="hidden" />
|
<FormInput id={`auth_provider_mappings_attributes.${index}.id`} register={register} type="hidden" />
|
||||||
<div className="local-data">
|
<div className="local-data">
|
||||||
@ -141,7 +166,7 @@ export const DataMappingForm = <TFieldValues extends FieldValues, TContext exten
|
|||||||
onClick={toggleTypeMappingModal(index)}
|
onClick={toggleTypeMappingModal(index)}
|
||||||
disabled={getField(output, index) === undefined}
|
disabled={getField(output, index) === undefined}
|
||||||
tooltip={t('app.admin.authentication.data_mapping_form.data_mapping')} />
|
tooltip={t('app.admin.authentication.data_mapping_form.data_mapping')} />
|
||||||
<FabButton icon={<i className="fa fa-trash" />} onClick={() => remove(index)} className="delete-button" />
|
<FabButton icon={<i className="fa fa-trash" />} onClick={() => removeMapping(index)} className="delete-button" />
|
||||||
<TypeMappingModal model={getModel(output, index)}
|
<TypeMappingModal model={getModel(output, index)}
|
||||||
field={getField(output, index)}
|
field={getField(output, index)}
|
||||||
type={getDataType(output, index)}
|
type={getDataType(output, index)}
|
||||||
|
24
app/frontend/src/javascript/components/authentication-provider/openid-connect-data-mapping-form.tsx
24
app/frontend/src/javascript/components/authentication-provider/openid-connect-data-mapping-form.tsx
@ -44,17 +44,19 @@ export const OpenidConnectDataMappingForm = <TFieldValues extends FieldValues>({
|
|||||||
const model = currentFormValues[index]?.local_model;
|
const model = currentFormValues[index]?.local_model;
|
||||||
const field = currentFormValues[index]?.local_field;
|
const field = currentFormValues[index]?.local_field;
|
||||||
const configuration = standardConfiguration[`${model}.${field}`];
|
const configuration = standardConfiguration[`${model}.${field}`];
|
||||||
setValue(
|
if (configuration) {
|
||||||
`auth_provider_mappings_attributes.${index}.api_field` as Path<TFieldValues>,
|
setValue(
|
||||||
configuration.api_field as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
`auth_provider_mappings_attributes.${index}.api_field` as Path<TFieldValues>,
|
||||||
);
|
configuration.api_field as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
||||||
if (configuration.transformation) {
|
);
|
||||||
Object.keys(configuration.transformation).forEach((key) => {
|
if (configuration.transformation) {
|
||||||
setValue(
|
Object.keys(configuration.transformation).forEach((key) => {
|
||||||
`auth_provider_mappings_attributes.${index}.transformation.${key}` as Path<TFieldValues>,
|
setValue(
|
||||||
configuration.transformation[key] as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
`auth_provider_mappings_attributes.${index}.transformation.${key}` as Path<TFieldValues>,
|
||||||
);
|
configuration.transformation[key] as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>
|
||||||
});
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ export type mappingType = 'string' | 'text' | 'date' | 'integer' | 'boolean';
|
|||||||
|
|
||||||
export interface AuthenticationProviderMapping {
|
export interface AuthenticationProviderMapping {
|
||||||
id?: number,
|
id?: number,
|
||||||
|
_destroy?: boolean,
|
||||||
local_model: 'user' | 'profile',
|
local_model: 'user' | 'profile',
|
||||||
local_field: string,
|
local_field: string,
|
||||||
api_field: string,
|
api_field: string,
|
||||||
|
@ -24,5 +24,13 @@
|
|||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.destroyed-item {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.new-item {
|
||||||
|
background-color: var(--information-lightest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user