mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2025-02-27 21:54:27 +01:00
(ui) form-select: onChange cb
This commit is contained in:
parent
468136603e
commit
29938957ff
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||||
import { react2angular } from 'react2angular';
|
import { react2angular } from 'react2angular';
|
||||||
import { AuthenticationProvider } from '../../models/authentication-provider';
|
import { AuthenticationProvider } from '../../models/authentication-provider';
|
||||||
@ -32,6 +32,7 @@ type selectProvidableTypeOption = { value: string, label: string };
|
|||||||
*/
|
*/
|
||||||
export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, onError, onSuccess }) => {
|
export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, onError, onSuccess }) => {
|
||||||
const { handleSubmit, register, control } = useForm<AuthenticationProvider>({ defaultValues: { ...provider } });
|
const { handleSubmit, register, control } = useForm<AuthenticationProvider>({ defaultValues: { ...provider } });
|
||||||
|
const [providableType, setProvidableType] = useState<string>(provider?.providable_type);
|
||||||
const { t } = useTranslation('shared');
|
const { t } = useTranslation('shared');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,11 +55,28 @@ export const ProviderForm: React.FC<ProviderFormProps> = ({ action, provider, on
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback triggered when the providable type is changed.
|
||||||
|
* Changing the providable type will change the form to match the new type.
|
||||||
|
*/
|
||||||
|
const onProvidableTypeChange = (type: string) => {
|
||||||
|
setProvidableType(type);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form className="provider-form" onSubmit={handleSubmit(onSubmit)}>
|
<form className="provider-form" onSubmit={handleSubmit(onSubmit)}>
|
||||||
<FormInput id="name" register={register} readOnly={action === 'update'} rules={{ required: true }} label={t('app.shared.authentication.name')} />
|
<FormInput id="name"
|
||||||
<FormSelect id="providable_type" control={control} options={buildProvidableTypeOptions()} label={t('app.shared.authentication.authentication_type')} rules={{ required: true }} />
|
register={register}
|
||||||
{provider?.providable_type === 'OAuth2Provider' && <Oauth2Form register={register} />}
|
readOnly={action === 'update'}
|
||||||
|
rules={{ required: true }}
|
||||||
|
label={t('app.shared.authentication.name')} />
|
||||||
|
<FormSelect id="providable_type"
|
||||||
|
control={control}
|
||||||
|
options={buildProvidableTypeOptions()}
|
||||||
|
label={t('app.shared.authentication.authentication_type')}
|
||||||
|
onChange={onProvidableTypeChange}
|
||||||
|
rules={{ required: true }} />
|
||||||
|
{providableType === 'OAuth2Provider' && <Oauth2Form register={register} />}
|
||||||
<input type={'submit'} />
|
<input type={'submit'} />
|
||||||
</form>
|
</form>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { SelectHTMLAttributes } from 'react';
|
import React from 'react';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
import { Controller, Path } from 'react-hook-form';
|
import { Controller, Path } from 'react-hook-form';
|
||||||
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||||
@ -6,11 +6,15 @@ import { FieldPath } from 'react-hook-form/dist/types/path';
|
|||||||
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
|
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
|
||||||
import { FormControlledComponent } from '../../models/form-component';
|
import { FormControlledComponent } from '../../models/form-component';
|
||||||
|
|
||||||
interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> {
|
interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends FormControlledComponent<TFieldValues, TContext> {
|
||||||
id: string,
|
id: string,
|
||||||
label?: string,
|
label?: string,
|
||||||
options: Array<selectOption<TOptionValue>>,
|
options: Array<selectOption<TOptionValue>>,
|
||||||
valuesDefault?: Array<TOptionValue>,
|
valuesDefault?: Array<TOptionValue>,
|
||||||
|
onChange?: (values: Array<TOptionValue>) => void,
|
||||||
|
className?: string,
|
||||||
|
placeholder?: string,
|
||||||
|
disabled?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -23,13 +27,23 @@ type selectOption<TOptionValue> = { value: TOptionValue, label: string };
|
|||||||
* This component is a wrapper around react-select to use with react-hook-form.
|
* This component is a wrapper around react-select to use with react-hook-form.
|
||||||
* It is a multi-select component.
|
* It is a multi-select component.
|
||||||
*/
|
*/
|
||||||
export const FormMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valuesDefault, error, rules, disabled }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
export const FormMultiSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valuesDefault, error, rules, disabled, onChange }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
||||||
const classNames = `
|
const classNames = `
|
||||||
form-item ${className || ''}
|
form-item ${className || ''}
|
||||||
${error && error[id] ? 'is-incorrect' : ''}
|
${error && error[id] ? 'is-incorrect' : ''}
|
||||||
${rules && rules.required ? 'is-required' : ''}
|
${rules && rules.required ? 'is-required' : ''}
|
||||||
${disabled ? 'is-disabled' : ''}`;
|
${disabled ? 'is-disabled' : ''}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following callback will trigger the onChange callback, if it was passed to this component,
|
||||||
|
* when the selected option changes.
|
||||||
|
*/
|
||||||
|
const onChangeCb = (newValues: Array<TOptionValue>): void => {
|
||||||
|
if (typeof onChange === 'function') {
|
||||||
|
onChange(newValues);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className={classNames}>
|
<label className={classNames}>
|
||||||
{label && <div className="form-item-header">
|
{label && <div className="form-item-header">
|
||||||
@ -40,15 +54,19 @@ export const FormMultiSelect = <TFieldValues extends FieldValues, TContext exten
|
|||||||
control={control}
|
control={control}
|
||||||
defaultValue={valuesDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
|
defaultValue={valuesDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
|
||||||
render={({ field: { onChange, value, ref } }) =>
|
render={({ field: { onChange, value, ref } }) =>
|
||||||
<Select inputRef={ref}
|
<Select ref={ref}
|
||||||
classNamePrefix="rs"
|
classNamePrefix="rs"
|
||||||
className="rs"
|
className="rs"
|
||||||
value={options.filter(c => value?.includes(c.value))}
|
value={options.filter(c => value?.includes(c.value))}
|
||||||
onChange={val => onChange(val.map(c => c.value))}
|
onChange={val => {
|
||||||
placeholder={placeholder}
|
const values = val?.map(c => c.value);
|
||||||
options={options}
|
onChangeCb(values);
|
||||||
isMulti />
|
onChange(values);
|
||||||
} />
|
}}
|
||||||
|
placeholder={placeholder}
|
||||||
|
options={options}
|
||||||
|
isMulti />
|
||||||
|
} />
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { SelectHTMLAttributes } from 'react';
|
import React from 'react';
|
||||||
import Select from 'react-select';
|
import Select from 'react-select';
|
||||||
import { Controller, Path } from 'react-hook-form';
|
import { Controller, Path } from 'react-hook-form';
|
||||||
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
import { FieldValues } from 'react-hook-form/dist/types/fields';
|
||||||
@ -6,11 +6,15 @@ import { FieldPath } from 'react-hook-form/dist/types/path';
|
|||||||
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
|
import { FieldPathValue, UnpackNestedValue } from 'react-hook-form/dist/types';
|
||||||
import { FormControlledComponent } from '../../models/form-component';
|
import { FormControlledComponent } from '../../models/form-component';
|
||||||
|
|
||||||
interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends SelectHTMLAttributes<HTMLSelectElement>, FormControlledComponent<TFieldValues, TContext> {
|
interface FormSelectProps<TFieldValues, TContext extends object, TOptionValue> extends FormControlledComponent<TFieldValues, TContext> {
|
||||||
id: string,
|
id: string,
|
||||||
label?: string,
|
label?: string,
|
||||||
options: Array<selectOption<TOptionValue>>,
|
options: Array<selectOption<TOptionValue>>,
|
||||||
valueDefault?: TOptionValue,
|
valueDefault?: TOptionValue,
|
||||||
|
onChange?: (value: TOptionValue) => void,
|
||||||
|
className?: string,
|
||||||
|
placeholder?: string,
|
||||||
|
disabled?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -22,13 +26,23 @@ type selectOption<TOptionValue> = { value: TOptionValue, label: string };
|
|||||||
/**
|
/**
|
||||||
* This component is a wrapper for react-select to use with react-hook-form
|
* This component is a wrapper for react-select to use with react-hook-form
|
||||||
*/
|
*/
|
||||||
export const FormSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valueDefault, error, rules, disabled }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
export const FormSelect = <TFieldValues extends FieldValues, TContext extends object, TOptionValue>({ id, label, className, control, placeholder, options, valueDefault, error, rules, disabled, onChange }: FormSelectProps<TFieldValues, TContext, TOptionValue>) => {
|
||||||
const classNames = `
|
const classNames = `
|
||||||
form-item ${className || ''}
|
form-item ${className || ''}
|
||||||
${error && error[id] ? 'is-incorrect' : ''}
|
${error && error[id] ? 'is-incorrect' : ''}
|
||||||
${rules && rules.required ? 'is-required' : ''}
|
${rules && rules.required ? 'is-required' : ''}
|
||||||
${disabled ? 'is-disabled' : ''}`;
|
${disabled ? 'is-disabled' : ''}`;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The following callback will trigger the onChange callback, if it was passed to this component,
|
||||||
|
* when the selected option changes.
|
||||||
|
*/
|
||||||
|
const onChangeCb = (newValue: TOptionValue): void => {
|
||||||
|
if (typeof onChange === 'function') {
|
||||||
|
onChange(newValue);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<label className={classNames}>
|
<label className={classNames}>
|
||||||
{label && <div className="form-item-header">
|
{label && <div className="form-item-header">
|
||||||
@ -39,14 +53,17 @@ export const FormSelect = <TFieldValues extends FieldValues, TContext extends ob
|
|||||||
control={control}
|
control={control}
|
||||||
defaultValue={valueDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
|
defaultValue={valueDefault as UnpackNestedValue<FieldPathValue<TFieldValues, Path<TFieldValues>>>}
|
||||||
render={({ field: { onChange, value, ref } }) =>
|
render={({ field: { onChange, value, ref } }) =>
|
||||||
<Select inputRef={ref}
|
<Select ref={ref}
|
||||||
classNamePrefix="rs"
|
classNamePrefix="rs"
|
||||||
className="rs"
|
className="rs"
|
||||||
value={options.find(c => c.value === value)}
|
value={options.find(c => c.value === value)}
|
||||||
onChange={val => onChange(val.value)}
|
onChange={val => {
|
||||||
placeholder={placeholder}
|
onChangeCb(val.value);
|
||||||
options={options} />
|
onChange(val.value);
|
||||||
} />
|
}}
|
||||||
|
placeholder={placeholder}
|
||||||
|
options={options} />
|
||||||
|
} />
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user