Feat/generic editable board card (#1089)
* Fixed BoardColumnMenu * Fixed naming * Optimized board loading * Added GenericEditableField * Introduce GenericEditableField for BoardCards * remove logs * delete unused files * fix stories --------- Co-authored-by: corentin <corentin@twenty.com>
This commit is contained in:
@ -0,0 +1,78 @@
|
||||
import { useContext, useRef, useState } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { BoardCardIdContext } from '@/ui/board/states/BoardCardIdContext';
|
||||
import {
|
||||
ViewFieldDefinition,
|
||||
ViewFieldNumberMetadata,
|
||||
} from '@/ui/editable-field/types/ViewField';
|
||||
import { TextInputEdit } from '@/ui/input/text/components/TextInputEdit';
|
||||
import {
|
||||
canBeCastAsIntegerOrNull,
|
||||
castAsIntegerOrNull,
|
||||
} from '~/utils/cast-as-integer-or-null';
|
||||
|
||||
import { useRegisterCloseFieldHandlers } from '../hooks/useRegisterCloseFieldHandlers';
|
||||
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
|
||||
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
|
||||
|
||||
type OwnProps = {
|
||||
viewField: ViewFieldDefinition<ViewFieldNumberMetadata>;
|
||||
};
|
||||
|
||||
export function GenericEditableNumberFieldEditMode({ viewField }: OwnProps) {
|
||||
const currentEntityId = useContext(BoardCardIdContext);
|
||||
|
||||
// TODO: we could use a hook that would return the field value with the right type
|
||||
const [fieldValue, setFieldValue] = useRecoilState<number | null>(
|
||||
genericEntityFieldFamilySelector({
|
||||
entityId: currentEntityId ?? '',
|
||||
fieldName: viewField.metadata.fieldName,
|
||||
}),
|
||||
);
|
||||
const [internalValue, setInternalValue] = useState(
|
||||
fieldValue ? fieldValue.toString() : '',
|
||||
);
|
||||
|
||||
const updateField = useUpdateGenericEntityField();
|
||||
|
||||
function handleSubmit() {
|
||||
if (!canBeCastAsIntegerOrNull(internalValue)) {
|
||||
return;
|
||||
}
|
||||
if (internalValue === fieldValue) return;
|
||||
|
||||
setFieldValue(castAsIntegerOrNull(internalValue));
|
||||
|
||||
if (currentEntityId && updateField) {
|
||||
updateField(
|
||||
currentEntityId,
|
||||
viewField,
|
||||
castAsIntegerOrNull(internalValue),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
setFieldValue(fieldValue);
|
||||
}
|
||||
|
||||
function handleChange(newValue: string) {
|
||||
setInternalValue(newValue);
|
||||
}
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
useRegisterCloseFieldHandlers(wrapperRef, handleSubmit, onCancel);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<TextInputEdit
|
||||
autoFocus
|
||||
value={internalValue ? internalValue.toString() : ''}
|
||||
onChange={(newValue: string) => {
|
||||
handleChange(newValue);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user