redesign-topics-adding-custom-params-design

This commit is contained in:
Azat Gataullin 2020-04-16 17:23:05 +03:00
parent e2918b41ca
commit 1fe6ec611c
5 changed files with 76 additions and 92 deletions

View file

@ -1,26 +1,20 @@
import React from 'react';
import CustomParamButton, { CustomParamButtonType } from './CustomParamButton';
import { isFirstParam } from './CustomParams';
interface Props {
index: string;
onAdd: (event: React.MouseEvent<HTMLButtonElement>) => void;
onRemove: (index: string) => void;
}
const CustomParamAction: React.FC<Props> = ({
index,
onAdd,
onRemove,
}) => (
const CustomParamAction: React.FC<Props> = ({ index, onRemove }) => (
<>
<label className='label'>&nbsp;</label>
{
isFirstParam(index)
? <CustomParamButton className="is-success" type={CustomParamButtonType.plus} onClick={onAdd} />
: <CustomParamButton className="is-danger" type={CustomParamButtonType.minus} onClick={() => onRemove(index)} />
}
<label className="label">&nbsp;</label>
<CustomParamButton
className="is-danger"
type={CustomParamButtonType.minus}
onClick={() => onRemove(index)}
/>
</>
)
);
export default CustomParamAction;

View file

@ -6,21 +6,28 @@ export enum CustomParamButtonType {
}
interface Props {
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void,
onClick: (event: React.MouseEvent<HTMLButtonElement>) => void;
className: string;
type: CustomParamButtonType;
btnText?: string;
}
const CustomParamButton: React.FC<Props> = ({
onClick,
className,
type,
btnText,
}) => (
<button className={`button ${className} is-outlined`} onClick={onClick}>
<button
type="button"
className={`button ${className} is-outlined`}
onClick={onClick}
>
{btnText && <span>{btnText}</span>}
<span className="icon">
<i className={`fas fa-lg ${type}`}></i>
<i className={`fas fa-lg ${type}`} />
</span>
</button>
)
);
export default CustomParamButton;

View file

@ -1,8 +1,8 @@
import React from 'react';
import { useFormContext, ErrorMessage } from 'react-hook-form';
import CustomParamOptions from './CustomParamOptions';
import { isFirstParam, INDEX_PREFIX } from './CustomParams';
import { TopicFormCustomParam } from 'redux/interfaces';
import CustomParamOptions from './CustomParamOptions';
import { INDEX_PREFIX } from './CustomParams';
interface Props {
isDisabled: boolean;
@ -10,19 +10,10 @@ interface Props {
name: string;
}
const CustomParamSelect: React.FC<Props> = ({
isDisabled,
index,
name,
}) => {
const { register, unregister, errors, getValues, triggerValidation } = useFormContext();
const CustomParamSelect: React.FC<Props> = ({ isDisabled, index, name }) => {
const { register, errors, getValues, triggerValidation } = useFormContext();
const optInputName = `${index}[name]`;
React.useEffect(
() => { if (isFirstParam(index)) { unregister(optInputName) } },
);
const selectedMustBeUniq = (selected: string) => {
const values = getValues({ nest: true });
const customParamsValues: TopicFormCustomParam = values.customParams;
@ -30,11 +21,12 @@ const CustomParamSelect: React.FC<Props> = ({
let valid = true;
for (const [key, customParam] of Object.entries(customParamsValues)) {
if (`${INDEX_PREFIX}.${key}` === index) { continue; }
if (selected === customParam.name) {
valid = false;
break;
};
if (`${INDEX_PREFIX}.${key}` !== index) {
if (selected === customParam.name) {
valid = false;
break;
}
}
}
return valid ? true : 'Custom Parameter must be unique';
@ -48,7 +40,7 @@ const CustomParamSelect: React.FC<Props> = ({
name={optInputName}
ref={register({
required: 'Custom Parameter is required.',
validate: { unique: selected => selectedMustBeUniq(selected) },
validate: { unique: (selected) => selectedMustBeUniq(selected) },
})}
onChange={() => triggerValidation(optInputName)}
disabled={isDisabled}
@ -57,7 +49,7 @@ const CustomParamSelect: React.FC<Props> = ({
<CustomParamOptions />
</select>
<p className="help is-danger">
<ErrorMessage errors={errors} name={optInputName}/>
<ErrorMessage errors={errors} name={optInputName} />
</p>
</div>
</>

View file

@ -1,7 +1,6 @@
import React from 'react';
import { useFormContext, ErrorMessage } from 'react-hook-form';
import { CUSTOM_PARAMS_OPTIONS } from './customParamsOptions';
import { isFirstParam } from './CustomParams';
interface Props {
isDisabled: boolean;
@ -16,7 +15,7 @@ const CustomParamValue: React.FC<Props> = ({
name,
defaultValue,
}) => {
const { register, unregister, errors, watch, setValue } = useFormContext();
const { register, errors, watch, setValue } = useFormContext();
const selectInputName = `${index}[name]`;
const valInputName = `${index}[value]`;
const selectedParamName = watch(selectInputName, name);
@ -31,12 +30,6 @@ const CustomParamValue: React.FC<Props> = ({
}
}, [selectedParamName]);
React.useEffect(() => {
if (isFirstParam(index)) {
unregister(valInputName);
}
});
return (
<>
<label className="label">Value</label>

View file

@ -5,22 +5,20 @@ import { TopicFormCustomParams } from 'redux/interfaces';
import CustomParamSelect from './CustomParamSelect';
import CustomParamValue from './CustomParamValue';
import CustomParamAction from './CustomParamAction';
import CustomParamButton, { CustomParamButtonType } from './CustomParamButton';
const DEFAULT_INDEX = 'default';
export const INDEX_PREFIX = 'customParams';
export const isFirstParam = (index: string) => (index === DEFAULT_INDEX);
interface Props {
isSubmitting: boolean;
}
const CustomParams: React.FC<Props> = ({
isSubmitting,
}) => {
const [formCustomParams, setFormCustomParams] = React.useState<TopicFormCustomParams>({
byIndex: { [DEFAULT_INDEX]: { name: '', value: '' } },
allIndexes: [DEFAULT_INDEX],
const CustomParams: React.FC<Props> = ({ isSubmitting }) => {
const [formCustomParams, setFormCustomParams] = React.useState<
TopicFormCustomParams
>({
byIndex: {},
allIndexes: [],
});
const onAdd = (event: React.MouseEvent<HTMLButtonElement>) => {
@ -34,54 +32,54 @@ const CustomParams: React.FC<Props> = ({
...formCustomParams.byIndex,
[newIndex]: { name: '', value: '' },
},
allIndexes: [
formCustomParams.allIndexes[0],
newIndex,
...formCustomParams.allIndexes.slice(1),
],
allIndexes: [newIndex, ...formCustomParams.allIndexes],
});
}
};
const onRemove = (index: string) => {
setFormCustomParams({
...formCustomParams,
byIndex: omit(formCustomParams.byIndex, index),
allIndexes: reject(formCustomParams.allIndexes, (i) => (i === index)),
allIndexes: reject(formCustomParams.allIndexes, (i) => i === index),
});
}
};
return (
<>
{
formCustomParams.allIndexes.map((index) => (
<div className="columns is-centered" key={index}>
<div className="column">
<CustomParamSelect
index={index}
isDisabled={isFirstParam(index) || isSubmitting}
name={formCustomParams.byIndex[index].name}
/>
</div>
<div className="column">
<CustomParamValue
index={index}
isDisabled={isFirstParam(index) || isSubmitting}
name={formCustomParams.byIndex[index].name}
defaultValue={formCustomParams.byIndex[index].value}
/>
</div>
<div className="column is-narrow">
<CustomParamAction
index={index}
onAdd={onAdd}
onRemove={onRemove}
/>
</div>
<div className="columns">
<div className="column">
<CustomParamButton
className="is-success"
type={CustomParamButtonType.plus}
onClick={onAdd}
btnText="Add Custom Parameter"
/>
</div>
</div>
{formCustomParams.allIndexes.map((index) => (
<div className="columns is-centered" key={index}>
<div className="column">
<CustomParamSelect
index={index}
isDisabled={isSubmitting}
name={formCustomParams.byIndex[index].name}
/>
</div>
))
}
<div className="column">
<CustomParamValue
index={index}
isDisabled={isSubmitting}
name={formCustomParams.byIndex[index].name}
defaultValue={formCustomParams.byIndex[index].value}
/>
</div>
<div className="column is-narrow">
<CustomParamAction index={index} onRemove={onRemove} />
</div>
</div>
))}
</>
);
};