@ -1,6 +1,7 @@
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { DateDisplay } from '@/ui/content-display/components/DateDisplay';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
|
||||
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
|
||||
@ -11,7 +12,6 @@ import { FieldDefinition } from '../types/FieldDefinition';
|
||||
import { FieldDateMetadata } from '../types/FieldMetadata';
|
||||
|
||||
import { EditableField } from './EditableField';
|
||||
import { GenericEditableDateFieldDisplayMode } from './GenericEditableDateFieldDisplayMode';
|
||||
import { GenericEditableDateFieldEditMode } from './GenericEditableDateFieldEditMode';
|
||||
|
||||
export function GenericEditableDateField() {
|
||||
@ -34,7 +34,7 @@ export function GenericEditableDateField() {
|
||||
<EditableField
|
||||
IconLabel={currentEditableFieldDefinition.Icon}
|
||||
editModeContent={<GenericEditableDateFieldEditMode />}
|
||||
displayModeContent={<GenericEditableDateFieldDisplayMode />}
|
||||
displayModeContent={<DateDisplay value={fieldValue} />}
|
||||
isDisplayModeContentEmpty={!fieldValue}
|
||||
/>
|
||||
</RecoilScope>
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { DateInputDisplay } from '@/ui/input/components/DateInputDisplay';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
|
||||
import { EditableFieldEntityIdContext } from '../contexts/EditableFieldEntityIdContext';
|
||||
import { genericEntityFieldFamilySelector } from '../states/selectors/genericEntityFieldFamilySelector';
|
||||
import { FieldDefinition } from '../types/FieldDefinition';
|
||||
import { FieldDateMetadata } from '../types/FieldMetadata';
|
||||
|
||||
export function GenericEditableDateFieldDisplayMode() {
|
||||
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
|
||||
const currentEditableFieldDefinition = useContext(
|
||||
EditableFieldDefinitionContext,
|
||||
) as FieldDefinition<FieldDateMetadata>;
|
||||
|
||||
const fieldValue = useRecoilValue<string>(
|
||||
genericEntityFieldFamilySelector({
|
||||
entityId: currentEditableFieldEntityId ?? '',
|
||||
fieldName: currentEditableFieldDefinition
|
||||
? currentEditableFieldDefinition.metadata.fieldName
|
||||
: '',
|
||||
}),
|
||||
);
|
||||
|
||||
const internalDateValue = fieldValue
|
||||
? parseDate(fieldValue).toJSDate()
|
||||
: null;
|
||||
|
||||
return <DateInputDisplay value={internalDateValue} />;
|
||||
}
|
||||
@ -1,13 +1,17 @@
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { DateInput } from '@/ui/input/components/DateInput';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
|
||||
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
|
||||
import { EditableFieldEntityIdContext } from '../contexts/EditableFieldEntityIdContext';
|
||||
import { useFieldInputEventHandlers } from '../hooks/useFieldInputEventHandlers';
|
||||
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
|
||||
import { genericEntityFieldFamilySelector } from '../states/selectors/genericEntityFieldFamilySelector';
|
||||
import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope';
|
||||
import { FieldDefinition } from '../types/FieldDefinition';
|
||||
import { FieldDateMetadata } from '../types/FieldMetadata';
|
||||
import { EditableFieldEditModeDate } from '../variants/components/EditableFieldEditModeDate';
|
||||
|
||||
export function GenericEditableDateFieldEditMode() {
|
||||
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
|
||||
@ -27,7 +31,21 @@ export function GenericEditableDateFieldEditMode() {
|
||||
|
||||
const updateField = useUpdateGenericEntityField();
|
||||
|
||||
function handleSubmit(newDateISO: string) {
|
||||
function handleSubmit(newDate: Nullable<Date>) {
|
||||
if (!newDate) {
|
||||
setFieldValue('');
|
||||
|
||||
if (currentEditableFieldEntityId && updateField) {
|
||||
updateField(
|
||||
currentEditableFieldEntityId,
|
||||
currentEditableFieldDefinition,
|
||||
'',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const newDateISO = newDate?.toISOString();
|
||||
|
||||
if (newDateISO === fieldValue || !newDateISO) return;
|
||||
|
||||
setFieldValue(newDateISO);
|
||||
@ -41,7 +59,18 @@ export function GenericEditableDateFieldEditMode() {
|
||||
}
|
||||
}
|
||||
|
||||
const { handleEnter, handleEscape, handleClickOutside } =
|
||||
useFieldInputEventHandlers({
|
||||
onSubmit: handleSubmit,
|
||||
});
|
||||
|
||||
return (
|
||||
<EditableFieldEditModeDate value={fieldValue} onChange={handleSubmit} />
|
||||
<DateInput
|
||||
hotkeyScope={EditableFieldHotkeyScope.EditableField}
|
||||
onClickOutside={handleClickOutside}
|
||||
onEnter={handleEnter}
|
||||
onEscape={handleEscape}
|
||||
value={fieldValue ? new Date(fieldValue) : null}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { TextDisplay } from '@/ui/content-display/components/TextDisplay';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
|
||||
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
|
||||
@ -33,7 +34,7 @@ export function GenericEditableNumberField() {
|
||||
<EditableField
|
||||
IconLabel={currentEditableFieldDefinition.Icon}
|
||||
editModeContent={<GenericEditableNumberFieldEditMode />}
|
||||
displayModeContent={fieldValue}
|
||||
displayModeContent={<TextDisplay text={fieldValue} />}
|
||||
isDisplayModeContentEmpty={!fieldValue}
|
||||
/>
|
||||
</RecoilScope>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useContext, useRef, useState } from 'react';
|
||||
import { useContext } from 'react';
|
||||
import { useRecoilState } from 'recoil';
|
||||
|
||||
import { TextInputEdit } from '@/ui/input/text/components/TextInputEdit';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import {
|
||||
canBeCastAsIntegerOrNull,
|
||||
castAsIntegerOrNull,
|
||||
@ -9,9 +9,10 @@ import {
|
||||
|
||||
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
|
||||
import { EditableFieldEntityIdContext } from '../contexts/EditableFieldEntityIdContext';
|
||||
import { useRegisterCloseFieldHandlers } from '../hooks/useRegisterCloseFieldHandlers';
|
||||
import { useFieldInputEventHandlers } from '../hooks/useFieldInputEventHandlers';
|
||||
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
|
||||
import { genericEntityFieldFamilySelector } from '../states/selectors/genericEntityFieldFamilySelector';
|
||||
import { EditableFieldHotkeyScope } from '../types/EditableFieldHotkeyScope';
|
||||
import { FieldDefinition } from '../types/FieldDefinition';
|
||||
import { FieldNumberMetadata } from '../types/FieldMetadata';
|
||||
|
||||
@ -30,51 +31,43 @@ export function GenericEditableNumberFieldEditMode() {
|
||||
: '',
|
||||
}),
|
||||
);
|
||||
const [internalValue, setInternalValue] = useState(
|
||||
fieldValue ? fieldValue.toString() : '',
|
||||
);
|
||||
|
||||
const updateField = useUpdateGenericEntityField();
|
||||
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
useRegisterCloseFieldHandlers(wrapperRef, handleSubmit, onCancel);
|
||||
|
||||
function handleSubmit() {
|
||||
if (!canBeCastAsIntegerOrNull(internalValue)) {
|
||||
function handleSubmit(newValue: string) {
|
||||
if (!canBeCastAsIntegerOrNull(newValue)) {
|
||||
return;
|
||||
}
|
||||
if (internalValue === fieldValue) return;
|
||||
|
||||
setFieldValue(castAsIntegerOrNull(internalValue));
|
||||
if (newValue === fieldValue) return;
|
||||
|
||||
const castedValue = castAsIntegerOrNull(newValue);
|
||||
|
||||
setFieldValue(castedValue);
|
||||
|
||||
if (currentEditableFieldEntityId && updateField) {
|
||||
updateField(
|
||||
currentEditableFieldEntityId,
|
||||
currentEditableFieldDefinition,
|
||||
castAsIntegerOrNull(internalValue),
|
||||
castedValue,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
setFieldValue(fieldValue);
|
||||
}
|
||||
|
||||
function handleChange(newValue: string) {
|
||||
setInternalValue(newValue);
|
||||
}
|
||||
const { handleEnter, handleEscape, handleClickOutside } =
|
||||
useFieldInputEventHandlers({
|
||||
onSubmit: handleSubmit,
|
||||
});
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
<TextInputEdit
|
||||
autoFocus
|
||||
placeholder={currentEditableFieldDefinition.metadata.placeHolder}
|
||||
value={internalValue ? internalValue.toString() : ''}
|
||||
onChange={(newValue: string) => {
|
||||
handleChange(newValue);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<TextInput
|
||||
autoFocus
|
||||
placeholder={currentEditableFieldDefinition.metadata.placeHolder}
|
||||
hotkeyScope={EditableFieldHotkeyScope.EditableField}
|
||||
value={fieldValue ? fieldValue.toString() : ''}
|
||||
onClickOutside={handleClickOutside}
|
||||
onEnter={handleEnter}
|
||||
onEscape={handleEscape}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { DateDisplay } from '@/ui/content-display/components/DateDisplay';
|
||||
import { EditableField } from '@/ui/editable-field/components/EditableField';
|
||||
import { FieldRecoilScopeContext } from '@/ui/editable-field/states/recoil-scope-contexts/FieldRecoilScopeContext';
|
||||
import { IconComponent } from '@/ui/icon/types/IconComponent';
|
||||
import { DateInputDisplay } from '@/ui/input/components/DateInputDisplay';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
@ -12,9 +12,16 @@ type OwnProps = {
|
||||
label?: string;
|
||||
value: string | null | undefined;
|
||||
onSubmit?: (newValue: string) => void;
|
||||
hotkeyScope: string;
|
||||
};
|
||||
|
||||
export function DateEditableField({ Icon, value, label, onSubmit }: OwnProps) {
|
||||
export function DateEditableField({
|
||||
Icon,
|
||||
value,
|
||||
label,
|
||||
onSubmit,
|
||||
hotkeyScope,
|
||||
}: OwnProps) {
|
||||
async function handleChange(newValue: string) {
|
||||
onSubmit?.(newValue);
|
||||
}
|
||||
@ -24,8 +31,6 @@ export function DateEditableField({ Icon, value, label, onSubmit }: OwnProps) {
|
||||
return (
|
||||
<RecoilScope SpecificContext={FieldRecoilScopeContext}>
|
||||
<EditableField
|
||||
// onSubmit={handleSubmit}
|
||||
// onCancel={handleCancel}
|
||||
IconLabel={Icon}
|
||||
label={label}
|
||||
editModeContent={
|
||||
@ -34,9 +39,10 @@ export function DateEditableField({ Icon, value, label, onSubmit }: OwnProps) {
|
||||
onChange={(newValue: string) => {
|
||||
handleChange(newValue);
|
||||
}}
|
||||
parentHotkeyScope={hotkeyScope}
|
||||
/>
|
||||
}
|
||||
displayModeContent={<DateInputDisplay value={internalDateValue} />}
|
||||
displayModeContent={<DateDisplay value={internalDateValue} />}
|
||||
isDisplayModeContentEmpty={!value}
|
||||
/>
|
||||
</RecoilScope>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
import { DateInputEdit } from '@/ui/input/components/DateInputEdit';
|
||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||
import { DateInput } from '@/ui/input/components/DateInput';
|
||||
import { Nullable } from '~/types/Nullable';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
import { useEditableField } from '../../hooks/useEditableField';
|
||||
@ -9,10 +9,15 @@ import { useEditableField } from '../../hooks/useEditableField';
|
||||
type OwnProps = {
|
||||
value: string;
|
||||
onChange?: (newValue: string) => void;
|
||||
parentHotkeyScope?: HotkeyScope;
|
||||
parentHotkeyScope: string;
|
||||
};
|
||||
|
||||
export function EditableFieldEditModeDate({ value, onChange }: OwnProps) {
|
||||
// TODO: refactor this component to use the same logic as the GenericDateField component
|
||||
export function EditableFieldEditModeDate({
|
||||
value,
|
||||
onChange,
|
||||
parentHotkeyScope,
|
||||
}: OwnProps) {
|
||||
const [internalValue, setInternalValue] = useState(value);
|
||||
|
||||
useEffect(() => {
|
||||
@ -21,17 +26,26 @@ export function EditableFieldEditModeDate({ value, onChange }: OwnProps) {
|
||||
|
||||
const { closeEditableField } = useEditableField();
|
||||
|
||||
function handleChange(newValue: string) {
|
||||
onChange?.(newValue);
|
||||
function handleClickOutside() {
|
||||
closeEditableField();
|
||||
}
|
||||
|
||||
function handleEnter(newValue: Nullable<Date>) {
|
||||
onChange?.(newValue?.toISOString() ?? '');
|
||||
closeEditableField();
|
||||
}
|
||||
|
||||
function handleEscape() {
|
||||
closeEditableField();
|
||||
}
|
||||
|
||||
return (
|
||||
<DateInputEdit
|
||||
<DateInput
|
||||
value={internalValue ? parseDate(internalValue).toJSDate() : new Date()}
|
||||
onChange={(newDate: Date) => {
|
||||
handleChange(newDate.toISOString());
|
||||
}}
|
||||
hotkeyScope={parentHotkeyScope}
|
||||
onClickOutside={handleClickOutside}
|
||||
onEnter={handleEnter}
|
||||
onEscape={handleEscape}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user