441/fix/clear cell while opening it by typing and delete value when I hit delete / backspace. (#2021)
- Use initial values when opening table cells and pass them to fields --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -11,16 +11,24 @@ export type CompanyPickerProps = {
|
|||||||
companyId: string | null;
|
companyId: string | null;
|
||||||
onSubmit: (newCompanyId: EntityForSelect | null) => void;
|
onSubmit: (newCompanyId: EntityForSelect | null) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
|
initialSearchFilter?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CompanyPicker = ({
|
export const CompanyPicker = ({
|
||||||
companyId,
|
companyId,
|
||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
|
initialSearchFilter,
|
||||||
}: CompanyPickerProps) => {
|
}: CompanyPickerProps) => {
|
||||||
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||||
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (initialSearchFilter) {
|
||||||
|
setRelationPickerSearchFilter(initialSearchFilter);
|
||||||
|
}
|
||||||
|
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
||||||
|
|
||||||
const companies = useFilteredSearchCompanyQuery({
|
const companies = useFilteredSearchCompanyQuery({
|
||||||
searchFilter: relationPickerSearchFilter,
|
searchFilter: relationPickerSearchFilter,
|
||||||
selectedIds: companyId ? [companyId] : [],
|
selectedIds: companyId ? [companyId] : [],
|
||||||
@ -32,10 +40,6 @@ export const CompanyPicker = ({
|
|||||||
onSubmit(selectedCompany ?? null);
|
onSubmit(selectedCompany ?? null);
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRelationPickerSearchFilter('');
|
|
||||||
}, [setRelationPickerSearchFilter]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SingleEntitySelect
|
<SingleEntitySelect
|
||||||
entitiesToSelect={companies.entitiesToSelect}
|
entitiesToSelect={companies.entitiesToSelect}
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
||||||
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/ui/input/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
@ -13,6 +15,7 @@ export type PeoplePickerProps = {
|
|||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
onCreate?: () => void;
|
onCreate?: () => void;
|
||||||
excludePersonIds?: string[];
|
excludePersonIds?: string[];
|
||||||
|
initialSearchFilter?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PersonForSelect = EntityForSelect & {
|
export type PersonForSelect = EntityForSelect & {
|
||||||
@ -26,10 +29,14 @@ export const PeoplePicker = ({
|
|||||||
onCancel,
|
onCancel,
|
||||||
onCreate,
|
onCreate,
|
||||||
excludePersonIds,
|
excludePersonIds,
|
||||||
|
initialSearchFilter,
|
||||||
}: PeoplePickerProps) => {
|
}: PeoplePickerProps) => {
|
||||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||||
relationPickerSearchFilterScopedState,
|
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||||
);
|
|
||||||
|
useEffect(() => {
|
||||||
|
setRelationPickerSearchFilter(initialSearchFilter ?? '');
|
||||||
|
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
||||||
|
|
||||||
const queryFilters = [
|
const queryFilters = [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { useEffect } from 'react';
|
|
||||||
import debounce from 'lodash.debounce';
|
import debounce from 'lodash.debounce';
|
||||||
|
|
||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
@ -31,10 +30,6 @@ export const useEntitySelectSearch = () => {
|
|||||||
setRelationPickerPreselectedId('');
|
setRelationPickerPreselectedId('');
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setRelationPickerSearchFilter('');
|
|
||||||
}, [setRelationPickerSearchFilter]);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
searchFilter: relationPickerSearchFilter,
|
searchFilter: relationPickerSearchFilter,
|
||||||
handleSearchFilterChange,
|
handleSearchFilterChange,
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { useContext } from 'react';
|
||||||
|
import { useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { FieldContext } from '../contexts/FieldContext';
|
||||||
|
import { entityFieldInitialValueFamilyState } from '../states/entityFieldInitialValueFamilyState';
|
||||||
|
|
||||||
|
export const useFieldInitialValue = () => {
|
||||||
|
const { entityId, fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
|
const fieldInitialValue = useRecoilValue(
|
||||||
|
entityFieldInitialValueFamilyState({
|
||||||
|
fieldId: fieldDefinition.fieldId,
|
||||||
|
entityId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
return fieldInitialValue;
|
||||||
|
};
|
||||||
@ -11,6 +11,9 @@ import { isFieldURL } from '../types/guards/isFieldURL';
|
|||||||
|
|
||||||
export const useGetButtonIcon = (): IconComponent | undefined => {
|
export const useGetButtonIcon = (): IconComponent | undefined => {
|
||||||
const { fieldDefinition } = useContext(FieldContext);
|
const { fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
|
if (!fieldDefinition) return undefined;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
isFieldURL(fieldDefinition) ||
|
isFieldURL(fieldDefinition) ||
|
||||||
isFieldEmail(fieldDefinition) ||
|
isFieldEmail(fieldDefinition) ||
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldChip } from '../../types/guards/isFieldChip';
|
import { isFieldChip } from '../../types/guards/isFieldChip';
|
||||||
@ -30,11 +31,25 @@ export const useChipField = () => {
|
|||||||
|
|
||||||
const entityType = fieldDefinition.metadata.relationType;
|
const entityType = fieldDefinition.metadata.relationType;
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialContentValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? contentFieldValue;
|
||||||
|
|
||||||
|
const initialAvatarValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value
|
||||||
|
? ''
|
||||||
|
: avatarFieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
contentFieldValue,
|
contentFieldValue,
|
||||||
|
initialContentValue,
|
||||||
setContentFieldValue,
|
setContentFieldValue,
|
||||||
avatarFieldValue,
|
avatarFieldValue,
|
||||||
|
initialAvatarValue,
|
||||||
setAvatarFieldValue,
|
setAvatarFieldValue,
|
||||||
entityType,
|
entityType,
|
||||||
entityId,
|
entityId,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldDoubleTextChip } from '../../types/guards/isFieldDoubleTextChip';
|
import { isFieldDoubleTextChip } from '../../types/guards/isFieldDoubleTextChip';
|
||||||
@ -40,6 +41,24 @@ export const useDoubleTextChipField = () => {
|
|||||||
|
|
||||||
const entityType = fieldDefinition.metadata.entityType;
|
const entityType = fieldDefinition.metadata.entityType;
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialFirstValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? firstValue;
|
||||||
|
|
||||||
|
const initialSecondValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value
|
||||||
|
? ''
|
||||||
|
: secondValue;
|
||||||
|
|
||||||
|
const initialAvatarUrl = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value
|
||||||
|
? ''
|
||||||
|
: avatarUrl;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
avatarUrl,
|
avatarUrl,
|
||||||
@ -52,5 +71,8 @@ export const useDoubleTextChipField = () => {
|
|||||||
entityType,
|
entityType,
|
||||||
entityId,
|
entityId,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
|
initialAvatarUrl,
|
||||||
|
initialFirstValue,
|
||||||
|
initialSecondValue,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldDoubleText } from '../../types/guards/isFieldDoubleText';
|
import { isFieldDoubleText } from '../../types/guards/isFieldDoubleText';
|
||||||
@ -25,6 +26,18 @@ export const useDoubleTextField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialFirstValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? firstValue;
|
||||||
|
|
||||||
|
const initialSecondValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value
|
||||||
|
? ''
|
||||||
|
: secondValue;
|
||||||
|
|
||||||
const fullValue = [firstValue, secondValue].filter(Boolean).join(' ');
|
const fullValue = [firstValue, secondValue].filter(Boolean).join(' ');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -32,6 +45,8 @@ export const useDoubleTextField = () => {
|
|||||||
secondValue,
|
secondValue,
|
||||||
setSecondValue,
|
setSecondValue,
|
||||||
firstValue,
|
firstValue,
|
||||||
|
initialFirstValue,
|
||||||
|
initialSecondValue,
|
||||||
setFirstValue,
|
setFirstValue,
|
||||||
fullValue,
|
fullValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldEmail } from '../../types/guards/isFieldEmail';
|
import { isFieldEmail } from '../../types/guards/isFieldEmail';
|
||||||
@ -20,9 +21,16 @@ export const useEmailField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { FieldMoneyAmountV2Value } from '../../types/FieldMetadata';
|
import { FieldMoneyAmountV2Value } from '../../types/FieldMetadata';
|
||||||
@ -33,9 +34,18 @@ export const useMoneyAmountV2Field = () => {
|
|||||||
persistField(newValue);
|
persistField(newValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue: FieldMoneyAmountV2Value = fieldInitialValue?.isEmpty
|
||||||
|
? { amount: 0, currency: '' }
|
||||||
|
: !isNaN(Number(fieldInitialValue?.value))
|
||||||
|
? { amount: Number(fieldInitialValue?.value), currency: '' }
|
||||||
|
: { amount: 0, currency: '' } ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistMoneyAmountV2Field,
|
persistMoneyAmountV2Field,
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
} from '~/utils/cast-as-integer-or-null';
|
} from '~/utils/cast-as-integer-or-null';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
@ -38,9 +39,18 @@ export const useMoneyField = () => {
|
|||||||
persistField(castedValue);
|
persistField(castedValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? null
|
||||||
|
: !isNaN(Number(fieldInitialValue?.value))
|
||||||
|
? Number(fieldInitialValue?.value)
|
||||||
|
: null ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistMoneyField,
|
persistMoneyField,
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import {
|
|||||||
} from '~/utils/cast-as-integer-or-null';
|
} from '~/utils/cast-as-integer-or-null';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
@ -38,9 +39,18 @@ export const useNumberField = () => {
|
|||||||
persistField(castedValue);
|
persistField(castedValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? null
|
||||||
|
: !isNaN(Number(fieldInitialValue?.value))
|
||||||
|
? Number(fieldInitialValue?.value)
|
||||||
|
: null ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistNumberField,
|
persistNumberField,
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { isPossiblePhoneNumber } from 'libphonenumber-js';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
@ -30,9 +31,16 @@ export const usePhoneField = () => {
|
|||||||
persistField(newPhoneValue);
|
persistField(newPhoneValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistPhoneField,
|
persistPhoneField,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldRelation } from '../../types/guards/isFieldRelation';
|
import { isFieldRelation } from '../../types/guards/isFieldRelation';
|
||||||
@ -21,9 +22,19 @@ export const useRelationField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialSearchValue = fieldInitialValue?.isEmpty
|
||||||
|
? null
|
||||||
|
: fieldInitialValue?.value;
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty ? null : fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
|
initialSearchValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
import { isFieldText } from '../../types/guards/isFieldText';
|
import { isFieldText } from '../../types/guards/isFieldText';
|
||||||
@ -20,9 +21,16 @@ export const useTextField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? fieldValue;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { useRecoilState } from 'recoil';
|
|||||||
import { isURL } from '~/utils/is-url';
|
import { isURL } from '~/utils/is-url';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata';
|
||||||
@ -23,6 +24,12 @@ export const useURLField = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue = fieldInitialValue?.isEmpty
|
||||||
|
? ''
|
||||||
|
: fieldInitialValue?.value ?? fieldValue;
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
const persistURLField = (newValue: string) => {
|
const persistURLField = (newValue: string) => {
|
||||||
@ -36,6 +43,7 @@ export const useURLField = () => {
|
|||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistURLField,
|
persistURLField,
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { useContext } from 'react';
|
|||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '../../contexts/FieldContext';
|
import { FieldContext } from '../../contexts/FieldContext';
|
||||||
|
import { useFieldInitialValue } from '../../hooks/useFieldInitialValue';
|
||||||
import { usePersistField } from '../../hooks/usePersistField';
|
import { usePersistField } from '../../hooks/usePersistField';
|
||||||
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector';
|
||||||
import { FieldURLV2Value } from '../../types/FieldMetadata';
|
import { FieldURLV2Value } from '../../types/FieldMetadata';
|
||||||
@ -23,6 +24,12 @@ export const useURLV2Field = () => {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const fieldInitialValue = useFieldInitialValue();
|
||||||
|
|
||||||
|
const initialValue: FieldURLV2Value = fieldInitialValue?.isEmpty
|
||||||
|
? { link: '', text: '' }
|
||||||
|
: { link: fieldInitialValue?.value ?? '', text: '' } ?? fieldValue;
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
const persistURLField = (newValue: FieldURLV2Value) => {
|
const persistURLField = (newValue: FieldURLV2Value) => {
|
||||||
@ -36,6 +43,7 @@ export const useURLV2Field = () => {
|
|||||||
return {
|
return {
|
||||||
fieldDefinition,
|
fieldDefinition,
|
||||||
fieldValue,
|
fieldValue,
|
||||||
|
initialValue,
|
||||||
setFieldValue,
|
setFieldValue,
|
||||||
hotkeyScope,
|
hotkeyScope,
|
||||||
persistURLField,
|
persistURLField,
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const ChipFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: ChipFieldInputProps) => {
|
}: ChipFieldInputProps) => {
|
||||||
const { fieldDefinition, contentFieldValue, hotkeyScope } = useChipField();
|
const { fieldDefinition, initialContentValue, hotkeyScope } = useChipField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export const ChipFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={contentFieldValue ?? ''}
|
value={initialContentValue}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -22,8 +22,12 @@ export const DoubleTextChipFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: DoubleTextChipFieldInputProps) => {
|
}: DoubleTextChipFieldInputProps) => {
|
||||||
const { fieldDefinition, firstValue, secondValue, hotkeyScope } =
|
const {
|
||||||
useDoubleTextChipField();
|
fieldDefinition,
|
||||||
|
initialFirstValue,
|
||||||
|
initialSecondValue,
|
||||||
|
hotkeyScope,
|
||||||
|
} = useDoubleTextChipField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -53,8 +57,8 @@ export const DoubleTextChipFieldInput = ({
|
|||||||
return (
|
return (
|
||||||
<FieldInputOverlay>
|
<FieldInputOverlay>
|
||||||
<DoubleTextInput
|
<DoubleTextInput
|
||||||
firstValue={firstValue ?? ''}
|
firstValue={initialFirstValue}
|
||||||
secondValue={secondValue ?? ''}
|
secondValue={initialSecondValue}
|
||||||
firstValuePlaceholder={fieldDefinition.metadata.firstValuePlaceholder}
|
firstValuePlaceholder={fieldDefinition.metadata.firstValuePlaceholder}
|
||||||
secondValuePlaceholder={fieldDefinition.metadata.secondValuePlaceholder}
|
secondValuePlaceholder={fieldDefinition.metadata.secondValuePlaceholder}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
|
|||||||
@ -22,8 +22,12 @@ export const DoubleTextFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: DoubleTextFieldInputProps) => {
|
}: DoubleTextFieldInputProps) => {
|
||||||
const { fieldDefinition, firstValue, secondValue, hotkeyScope } =
|
const {
|
||||||
useDoubleTextField();
|
fieldDefinition,
|
||||||
|
initialFirstValue,
|
||||||
|
initialSecondValue,
|
||||||
|
hotkeyScope,
|
||||||
|
} = useDoubleTextField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -53,8 +57,8 @@ export const DoubleTextFieldInput = ({
|
|||||||
return (
|
return (
|
||||||
<FieldInputOverlay>
|
<FieldInputOverlay>
|
||||||
<DoubleTextInput
|
<DoubleTextInput
|
||||||
firstValue={firstValue ?? ''}
|
firstValue={initialFirstValue}
|
||||||
secondValue={secondValue ?? ''}
|
secondValue={initialSecondValue}
|
||||||
firstValuePlaceholder={fieldDefinition.metadata.firstValuePlaceholder}
|
firstValuePlaceholder={fieldDefinition.metadata.firstValuePlaceholder}
|
||||||
secondValuePlaceholder={fieldDefinition.metadata.secondValuePlaceholder}
|
secondValuePlaceholder={fieldDefinition.metadata.secondValuePlaceholder}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const EmailFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: EmailFieldInputProps) => {
|
}: EmailFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope } = useEmailField();
|
const { fieldDefinition, initialValue, hotkeyScope } = useEmailField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export const EmailFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue ?? ''}
|
value={initialValue}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ export const MoneyAmountV2FieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: MoneyAmountV2FieldInputProps) => {
|
}: MoneyAmountV2FieldInputProps) => {
|
||||||
const { fieldValue, hotkeyScope } = useMoneyAmountV2Field();
|
const { hotkeyScope, initialValue } = useMoneyAmountV2Field();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ export const MoneyAmountV2FieldInput = ({
|
|||||||
return (
|
return (
|
||||||
<FieldInputOverlay>
|
<FieldInputOverlay>
|
||||||
<DoubleTextInput
|
<DoubleTextInput
|
||||||
firstValue={fieldValue.amount?.toString() ?? ''}
|
firstValue={initialValue.amount?.toString() ?? ''}
|
||||||
secondValue={fieldValue.currency ?? ''}
|
secondValue={initialValue.currency ?? ''}
|
||||||
firstValuePlaceholder="Amount"
|
firstValuePlaceholder="Amount"
|
||||||
secondValuePlaceholder="Currency"
|
secondValuePlaceholder="Currency"
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const MoneyFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: MoneyFieldInputProps) => {
|
}: MoneyFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope, persistMoneyField } =
|
const { fieldDefinition, hotkeyScope, persistMoneyField, initialValue } =
|
||||||
useMoneyField();
|
useMoneyField();
|
||||||
|
|
||||||
const handleEnter = (newText: string) => {
|
const handleEnter = (newText: string) => {
|
||||||
@ -52,7 +52,7 @@ export const MoneyFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue?.toLocaleString() ?? ''}
|
value={initialValue?.toLocaleString() ?? ''}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const NumberFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: NumberFieldInputProps) => {
|
}: NumberFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope, persistNumberField } =
|
const { fieldDefinition, initialValue, hotkeyScope, persistNumberField } =
|
||||||
useNumberField();
|
useNumberField();
|
||||||
|
|
||||||
const handleEnter = (newText: string) => {
|
const handleEnter = (newText: string) => {
|
||||||
@ -52,7 +52,7 @@ export const NumberFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue?.toString() ?? ''}
|
value={initialValue?.toString() ?? ''}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const PhoneFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: PhoneFieldInputProps) => {
|
}: PhoneFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope, persistPhoneField } =
|
const { fieldDefinition, initialValue, hotkeyScope, persistPhoneField } =
|
||||||
usePhoneField();
|
usePhoneField();
|
||||||
|
|
||||||
const handleEnter = (newText: string) => {
|
const handleEnter = (newText: string) => {
|
||||||
@ -51,7 +51,7 @@ export const PhoneFieldInput = ({
|
|||||||
<PhoneInput
|
<PhoneInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue ?? ''}
|
value={initialValue}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CompanyPicker } from '@/companies/components/CompanyPicker';
|
import { CompanyPicker } from '@/companies/components/CompanyPicker';
|
||||||
@ -26,7 +27,8 @@ export const RelationFieldInput = ({
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
}: RelationFieldInputProps) => {
|
}: RelationFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue } = useRelationField();
|
const { fieldDefinition, initialValue, initialSearchValue } =
|
||||||
|
useRelationField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -34,26 +36,31 @@ export const RelationFieldInput = ({
|
|||||||
onSubmit?.(() => persistField(newEntity?.originalEntity ?? null));
|
onSubmit?.(() => persistField(newEntity?.originalEntity ?? null));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useEffect(() => {}, [initialSearchValue]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledRelationPickerContainer>
|
<StyledRelationPickerContainer>
|
||||||
{fieldDefinition.metadata.relationType === Entity.Person ? (
|
{fieldDefinition.metadata.relationType === Entity.Person ? (
|
||||||
<PeoplePicker
|
<PeoplePicker
|
||||||
personId={fieldValue?.id ?? ''}
|
personId={initialValue?.id ?? ''}
|
||||||
companyId={fieldValue?.companyId ?? ''}
|
companyId={initialValue?.companyId ?? ''}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
|
initialSearchFilter={initialSearchValue}
|
||||||
/>
|
/>
|
||||||
) : fieldDefinition.metadata.relationType === Entity.User ? (
|
) : fieldDefinition.metadata.relationType === Entity.User ? (
|
||||||
<UserPicker
|
<UserPicker
|
||||||
userId={fieldValue?.id ?? ''}
|
userId={initialValue?.id ?? ''}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
|
initialSearchFilter={initialSearchValue}
|
||||||
/>
|
/>
|
||||||
) : fieldDefinition.metadata.relationType === Entity.Company ? (
|
) : fieldDefinition.metadata.relationType === Entity.Company ? (
|
||||||
<CompanyPicker
|
<CompanyPicker
|
||||||
companyId={fieldValue?.id ?? ''}
|
companyId={initialValue?.id ?? ''}
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
onCancel={onCancel}
|
onCancel={onCancel}
|
||||||
|
initialSearchFilter={initialSearchValue}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</StyledRelationPickerContainer>
|
</StyledRelationPickerContainer>
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const TextFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: TextFieldInputProps) => {
|
}: TextFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope } = useTextField();
|
const { fieldDefinition, initialValue, hotkeyScope } = useTextField();
|
||||||
|
|
||||||
const persistField = usePersistField();
|
const persistField = usePersistField();
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export const TextFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue ?? ''}
|
value={initialValue}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const URLFieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: URLFieldInputProps) => {
|
}: URLFieldInputProps) => {
|
||||||
const { fieldDefinition, fieldValue, hotkeyScope, persistURLField } =
|
const { fieldDefinition, initialValue, hotkeyScope, persistURLField } =
|
||||||
useURLField();
|
useURLField();
|
||||||
|
|
||||||
const handleEnter = (newText: string) => {
|
const handleEnter = (newText: string) => {
|
||||||
@ -51,7 +51,7 @@ export const URLFieldInput = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
placeholder={fieldDefinition.metadata.placeHolder}
|
placeholder={fieldDefinition.metadata.placeHolder}
|
||||||
autoFocus
|
autoFocus
|
||||||
value={fieldValue ?? ''}
|
value={initialValue}
|
||||||
onClickOutside={handleClickOutside}
|
onClickOutside={handleClickOutside}
|
||||||
onEnter={handleEnter}
|
onEnter={handleEnter}
|
||||||
onEscape={handleEscape}
|
onEscape={handleEscape}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ export const URLV2FieldInput = ({
|
|||||||
onTab,
|
onTab,
|
||||||
onShiftTab,
|
onShiftTab,
|
||||||
}: URLV2FieldInputProps) => {
|
}: URLV2FieldInputProps) => {
|
||||||
const { fieldValue, hotkeyScope, persistURLField } = useURLV2Field();
|
const { initialValue, hotkeyScope, persistURLField } = useURLV2Field();
|
||||||
|
|
||||||
const handleEnter = (newURL: FieldDoubleText) => {
|
const handleEnter = (newURL: FieldDoubleText) => {
|
||||||
onEnter?.(() =>
|
onEnter?.(() =>
|
||||||
@ -73,8 +73,8 @@ export const URLV2FieldInput = ({
|
|||||||
return (
|
return (
|
||||||
<FieldInputOverlay>
|
<FieldInputOverlay>
|
||||||
<DoubleTextInput
|
<DoubleTextInput
|
||||||
firstValue={fieldValue.link}
|
firstValue={initialValue.link}
|
||||||
secondValue={fieldValue.text}
|
secondValue={initialValue.text}
|
||||||
firstValuePlaceholder={'Link'}
|
firstValuePlaceholder={'Link'}
|
||||||
secondValuePlaceholder={'Label'}
|
secondValuePlaceholder={'Label'}
|
||||||
hotkeyScope={hotkeyScope}
|
hotkeyScope={hotkeyScope}
|
||||||
|
|||||||
@ -0,0 +1,11 @@
|
|||||||
|
import { atomFamily } from 'recoil';
|
||||||
|
|
||||||
|
import { FieldInitialValue } from '../types/FieldInitialValue';
|
||||||
|
|
||||||
|
export const entityFieldInitialValueFamilyState = atomFamily<
|
||||||
|
FieldInitialValue | undefined,
|
||||||
|
{ entityId: string; fieldId: string }
|
||||||
|
>({
|
||||||
|
key: 'entityFieldInitialValueFamilyState',
|
||||||
|
default: undefined,
|
||||||
|
});
|
||||||
@ -2,6 +2,7 @@ import { selectorFamily } from 'recoil';
|
|||||||
|
|
||||||
import { FieldDefinition } from '../../types/FieldDefinition';
|
import { FieldDefinition } from '../../types/FieldDefinition';
|
||||||
import { FieldMetadata } from '../../types/FieldMetadata';
|
import { FieldMetadata } from '../../types/FieldMetadata';
|
||||||
|
import { isFieldBoolean } from '../../types/guards/isFieldBoolean';
|
||||||
import { isFieldChip } from '../../types/guards/isFieldChip';
|
import { isFieldChip } from '../../types/guards/isFieldChip';
|
||||||
import { isFieldDate } from '../../types/guards/isFieldDate';
|
import { isFieldDate } from '../../types/guards/isFieldDate';
|
||||||
import { isFieldDoubleTextChip } from '../../types/guards/isFieldDoubleTextChip';
|
import { isFieldDoubleTextChip } from '../../types/guards/isFieldDoubleTextChip';
|
||||||
@ -35,6 +36,7 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
|
|||||||
isFieldNumber(fieldDefinition) ||
|
isFieldNumber(fieldDefinition) ||
|
||||||
isFieldMoney(fieldDefinition) ||
|
isFieldMoney(fieldDefinition) ||
|
||||||
isFieldEmail(fieldDefinition) ||
|
isFieldEmail(fieldDefinition) ||
|
||||||
|
isFieldBoolean(fieldDefinition) ||
|
||||||
isFieldPhone(fieldDefinition)
|
isFieldPhone(fieldDefinition)
|
||||||
) {
|
) {
|
||||||
const fieldName = fieldDefinition.metadata.fieldName;
|
const fieldName = fieldDefinition.metadata.fieldName;
|
||||||
@ -88,6 +90,10 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({
|
|||||||
contentFieldSecondValue === undefined ||
|
contentFieldSecondValue === undefined ||
|
||||||
contentFieldSecondValue === '')
|
contentFieldSecondValue === '')
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
throw new Error(
|
||||||
|
`Entity field type not supported in isEntityFieldEmptyFamilySelector : ${fieldDefinition.type}}`,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -0,0 +1,4 @@
|
|||||||
|
export type FieldInitialValue = {
|
||||||
|
isEmpty?: boolean;
|
||||||
|
value?: string;
|
||||||
|
};
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
import { atomFamily } from 'recoil';
|
||||||
|
|
||||||
|
import { TableCellInitialValue } from '../types/TableCellInitialValue';
|
||||||
|
import { TableCellPosition } from '../types/TableCellPosition';
|
||||||
|
|
||||||
|
export const tableCellInitialValueFamilyState = atomFamily<
|
||||||
|
TableCellInitialValue | undefined,
|
||||||
|
TableCellPosition
|
||||||
|
>({
|
||||||
|
key: 'tableCellInitialValueFamilyState',
|
||||||
|
default: undefined,
|
||||||
|
});
|
||||||
@ -1,13 +1,8 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
|
|
||||||
import { IconArrowUpRight } from '@/ui/display/icon';
|
|
||||||
import { FieldDisplay } from '@/ui/object/field/components/FieldDisplay';
|
import { FieldDisplay } from '@/ui/object/field/components/FieldDisplay';
|
||||||
import { FieldInput } from '@/ui/object/field/components/FieldInput';
|
import { FieldInput } from '@/ui/object/field/components/FieldInput';
|
||||||
import { useGetButtonIcon } from '@/ui/object/field/hooks/useGetButtonIcon';
|
|
||||||
import { FieldInputEvent } from '@/ui/object/field/types/FieldInputEvent';
|
import { FieldInputEvent } from '@/ui/object/field/types/FieldInputEvent';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
|
|
||||||
import { ColumnIndexContext } from '../../contexts/ColumnIndexContext';
|
|
||||||
import { useMoveSoftFocus } from '../../hooks/useMoveSoftFocus';
|
import { useMoveSoftFocus } from '../../hooks/useMoveSoftFocus';
|
||||||
import { useTableCell } from '../hooks/useTableCell';
|
import { useTableCell } from '../hooks/useTableCell';
|
||||||
|
|
||||||
@ -18,10 +13,6 @@ export const TableCell = ({
|
|||||||
}: {
|
}: {
|
||||||
customHotkeyScope: HotkeyScope;
|
customHotkeyScope: HotkeyScope;
|
||||||
}) => {
|
}) => {
|
||||||
const isFirstColumn = useContext(ColumnIndexContext) === 0;
|
|
||||||
|
|
||||||
const buttonIcon = useGetButtonIcon();
|
|
||||||
|
|
||||||
const { closeTableCell } = useTableCell();
|
const { closeTableCell } = useTableCell();
|
||||||
|
|
||||||
const { moveLeft, moveRight, moveDown } = useMoveSoftFocus();
|
const { moveLeft, moveRight, moveDown } = useMoveSoftFocus();
|
||||||
@ -72,7 +63,6 @@ export const TableCell = ({
|
|||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
nonEditModeContent={<FieldDisplay />}
|
nonEditModeContent={<FieldDisplay />}
|
||||||
buttonIcon={isFirstColumn ? IconArrowUpRight : buttonIcon}
|
|
||||||
></TableCellContainer>
|
></TableCellContainer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
import { ReactElement, useContext, useState } from 'react';
|
import { ReactElement, useContext, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
|
import { IconArrowUpRight } from '@/ui/display/icon';
|
||||||
|
import { useGetButtonIcon } from '@/ui/object/field/hooks/useGetButtonIcon';
|
||||||
import { useIsFieldEmpty } from '@/ui/object/field/hooks/useIsFieldEmpty';
|
import { useIsFieldEmpty } from '@/ui/object/field/hooks/useIsFieldEmpty';
|
||||||
import { useIsFieldInputOnly } from '@/ui/object/field/hooks/useIsFieldInputOnly';
|
import { useIsFieldInputOnly } from '@/ui/object/field/hooks/useIsFieldInputOnly';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
@ -39,7 +40,6 @@ export type TableCellContainerProps = {
|
|||||||
editHotkeyScope?: HotkeyScope;
|
editHotkeyScope?: HotkeyScope;
|
||||||
transparent?: boolean;
|
transparent?: boolean;
|
||||||
maxContentWidth?: number;
|
maxContentWidth?: number;
|
||||||
buttonIcon?: IconComponent;
|
|
||||||
onSubmit?: () => void;
|
onSubmit?: () => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
};
|
};
|
||||||
@ -54,7 +54,6 @@ export const TableCellContainer = ({
|
|||||||
editModeContent,
|
editModeContent,
|
||||||
nonEditModeContent,
|
nonEditModeContent,
|
||||||
editHotkeyScope,
|
editHotkeyScope,
|
||||||
buttonIcon,
|
|
||||||
}: TableCellContainerProps) => {
|
}: TableCellContainerProps) => {
|
||||||
const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode();
|
const { isCurrentTableCellInEditMode } = useCurrentTableCellEditMode();
|
||||||
|
|
||||||
@ -95,6 +94,12 @@ export const TableCellContainer = ({
|
|||||||
|
|
||||||
const isEmpty = useIsFieldEmpty();
|
const isEmpty = useIsFieldEmpty();
|
||||||
|
|
||||||
|
const isFirstColumn = useContext(ColumnIndexContext) === 0;
|
||||||
|
|
||||||
|
const customButtonIcon = useGetButtonIcon();
|
||||||
|
|
||||||
|
const buttonIcon = isFirstColumn ? IconArrowUpRight : customButtonIcon;
|
||||||
|
|
||||||
const showButton =
|
const showButton =
|
||||||
!!buttonIcon &&
|
!!buttonIcon &&
|
||||||
hasSoftFocus &&
|
hasSoftFocus &&
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { PropsWithChildren, useEffect, useRef } from 'react';
|
import { PropsWithChildren, useEffect, useRef } from 'react';
|
||||||
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
import { useIsFieldInputOnly } from '@/ui/object/field/hooks/useIsFieldInputOnly';
|
import { useIsFieldInputOnly } from '@/ui/object/field/hooks/useIsFieldInputOnly';
|
||||||
import { useToggleEditOnlyInput } from '@/ui/object/field/hooks/useToggleEditOnlyInput';
|
import { useToggleEditOnlyInput } from '@/ui/object/field/hooks/useToggleEditOnlyInput';
|
||||||
@ -26,7 +27,25 @@ export const TableCellSoftFocusMode = ({
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
'enter',
|
[Key.Backspace, Key.Delete],
|
||||||
|
() => {
|
||||||
|
if (!isFieldInputOnly) {
|
||||||
|
openTableCell({
|
||||||
|
initialValue: {
|
||||||
|
isEmpty: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TableHotkeyScope.TableSoftFocus,
|
||||||
|
[openTableCell],
|
||||||
|
{
|
||||||
|
enabled: !isFieldInputOnly,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
useScopedHotkeys(
|
||||||
|
Key.Enter,
|
||||||
() => {
|
() => {
|
||||||
if (!isFieldInputOnly) {
|
if (!isFieldInputOnly) {
|
||||||
openTableCell();
|
openTableCell();
|
||||||
@ -42,6 +61,10 @@ export const TableCellSoftFocusMode = ({
|
|||||||
'*',
|
'*',
|
||||||
(keyboardEvent) => {
|
(keyboardEvent) => {
|
||||||
if (!isFieldInputOnly) {
|
if (!isFieldInputOnly) {
|
||||||
|
keyboardEvent.preventDefault();
|
||||||
|
keyboardEvent.stopPropagation();
|
||||||
|
keyboardEvent.stopImmediatePropagation();
|
||||||
|
|
||||||
const isWritingText =
|
const isWritingText =
|
||||||
!isNonTextWritingKey(keyboardEvent.key) &&
|
!isNonTextWritingKey(keyboardEvent.key) &&
|
||||||
!keyboardEvent.ctrlKey &&
|
!keyboardEvent.ctrlKey &&
|
||||||
@ -51,7 +74,11 @@ export const TableCellSoftFocusMode = ({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
openTableCell();
|
openTableCell({
|
||||||
|
initialValue: {
|
||||||
|
value: keyboardEvent.key,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
TableHotkeyScope.TableSoftFocus,
|
TableHotkeyScope.TableSoftFocus,
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { tableCellInitialValueFamilyState } from '../../states/tableCellInitialValueFamilyState';
|
||||||
|
|
||||||
|
import { useCurrentTableCellPosition } from './useCurrentCellPosition';
|
||||||
|
|
||||||
|
export const useCurrentTableCellInitialValue = () => {
|
||||||
|
const currentTableCellPosition = useCurrentTableCellPosition();
|
||||||
|
|
||||||
|
const [currentTableCellInitialValue, setCurrentTableCellInitialValue] =
|
||||||
|
useRecoilState(tableCellInitialValueFamilyState(currentTableCellPosition));
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentTableCellInitialValue,
|
||||||
|
setCurrentTableCellInitialValue,
|
||||||
|
};
|
||||||
|
};
|
||||||
@ -1,8 +1,11 @@
|
|||||||
import { useContext } from 'react';
|
import { useContext } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
|
import { FieldContext } from '@/ui/object/field/contexts/FieldContext';
|
||||||
import { useIsFieldEmpty } from '@/ui/object/field/hooks/useIsFieldEmpty';
|
import { useIsFieldEmpty } from '@/ui/object/field/hooks/useIsFieldEmpty';
|
||||||
|
import { entityFieldInitialValueFamilyState } from '@/ui/object/field/states/entityFieldInitialValueFamilyState';
|
||||||
|
import { FieldInitialValue } from '@/ui/object/field/types/FieldInitialValue';
|
||||||
import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
|
import { useDragSelect } from '@/ui/utilities/drag-select/hooks/useDragSelect';
|
||||||
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
||||||
@ -28,12 +31,6 @@ export const useTableCell = () => {
|
|||||||
|
|
||||||
const customCellHotkeyScope = useContext(CellHotkeyScopeContext);
|
const customCellHotkeyScope = useContext(CellHotkeyScopeContext);
|
||||||
|
|
||||||
const closeTableCell = () => {
|
|
||||||
setDragSelectionStartEnabled(true);
|
|
||||||
closeCurrentTableCellInEditMode();
|
|
||||||
setHotkeyScope(TableHotkeyScope.TableSoftFocus);
|
|
||||||
};
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const isFirstColumnCell = useContext(ColumnIndexContext) === 0;
|
const isFirstColumnCell = useContext(ColumnIndexContext) === 0;
|
||||||
@ -42,7 +39,14 @@ export const useTableCell = () => {
|
|||||||
|
|
||||||
const { entityId, fieldDefinition } = useContext(FieldContext);
|
const { entityId, fieldDefinition } = useContext(FieldContext);
|
||||||
|
|
||||||
const openTableCell = () => {
|
const [, setFieldInitialValue] = useRecoilState(
|
||||||
|
entityFieldInitialValueFamilyState({
|
||||||
|
entityId,
|
||||||
|
fieldId: fieldDefinition.fieldId,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const openTableCell = (options?: { initialValue?: FieldInitialValue }) => {
|
||||||
if (isFirstColumnCell && !isEmpty && fieldDefinition.basePathToShowPage) {
|
if (isFirstColumnCell && !isEmpty && fieldDefinition.basePathToShowPage) {
|
||||||
navigate(`${fieldDefinition.basePathToShowPage}${entityId}`);
|
navigate(`${fieldDefinition.basePathToShowPage}${entityId}`);
|
||||||
return;
|
return;
|
||||||
@ -51,6 +55,10 @@ export const useTableCell = () => {
|
|||||||
setDragSelectionStartEnabled(false);
|
setDragSelectionStartEnabled(false);
|
||||||
setCurrentTableCellInEditMode();
|
setCurrentTableCellInEditMode();
|
||||||
|
|
||||||
|
if (options?.initialValue) {
|
||||||
|
setFieldInitialValue(options.initialValue);
|
||||||
|
}
|
||||||
|
|
||||||
if (customCellHotkeyScope) {
|
if (customCellHotkeyScope) {
|
||||||
setHotkeyScope(
|
setHotkeyScope(
|
||||||
customCellHotkeyScope.scope,
|
customCellHotkeyScope.scope,
|
||||||
@ -61,6 +69,13 @@ export const useTableCell = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const closeTableCell = () => {
|
||||||
|
setDragSelectionStartEnabled(true);
|
||||||
|
closeCurrentTableCellInEditMode();
|
||||||
|
setFieldInitialValue(undefined);
|
||||||
|
setHotkeyScope(TableHotkeyScope.TableSoftFocus);
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
closeTableCell,
|
closeTableCell,
|
||||||
openTableCell,
|
openTableCell,
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
import { useFilteredSearchEntityQuery } from '@/search/hooks/useFilteredSearchEntityQuery';
|
||||||
import { IconUserCircle } from '@/ui/display/icon';
|
import { IconUserCircle } from '@/ui/display/icon';
|
||||||
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
import { SingleEntitySelect } from '@/ui/input/relation-picker/components/SingleEntitySelect';
|
||||||
@ -12,6 +14,7 @@ export type UserPickerProps = {
|
|||||||
onSubmit: (newUser: EntityForSelect | null) => void;
|
onSubmit: (newUser: EntityForSelect | null) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
width?: number;
|
width?: number;
|
||||||
|
initialSearchFilter?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type UserForSelect = EntityForSelect & {
|
type UserForSelect = EntityForSelect & {
|
||||||
@ -23,10 +26,14 @@ export const UserPicker = ({
|
|||||||
onSubmit,
|
onSubmit,
|
||||||
onCancel,
|
onCancel,
|
||||||
width,
|
width,
|
||||||
|
initialSearchFilter,
|
||||||
}: UserPickerProps) => {
|
}: UserPickerProps) => {
|
||||||
const [relationPickerSearchFilter] = useRecoilScopedState(
|
const [relationPickerSearchFilter, setRelationPickerSearchFilter] =
|
||||||
relationPickerSearchFilterScopedState,
|
useRecoilScopedState(relationPickerSearchFilterScopedState);
|
||||||
);
|
|
||||||
|
useEffect(() => {
|
||||||
|
setRelationPickerSearchFilter(initialSearchFilter ?? '');
|
||||||
|
}, [initialSearchFilter, setRelationPickerSearchFilter]);
|
||||||
|
|
||||||
const users = useFilteredSearchEntityQuery({
|
const users = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchUserQuery,
|
queryHook: useSearchUserQuery,
|
||||||
|
|||||||
Reference in New Issue
Block a user