refactoring editableFieldContext to match with table implementation (#1164)

This commit is contained in:
Weiko 2023-08-10 12:26:05 -07:00 committed by GitHub
parent a12b6c4bda
commit 4288cef096
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 173 additions and 128 deletions

View File

@ -7,7 +7,9 @@ import { selectedBoardCardIdsState } from '@/ui/board/states/selectedBoardCardId
import { viewFieldsDefinitionsState } from '@/ui/board/states/viewFieldsDefinitionsState';
import { EntityChipVariant } from '@/ui/chip/components/EntityChip';
import { GenericEditableField } from '@/ui/editable-field/components/GenericEditableField';
import { EditableFieldContext } from '@/ui/editable-field/states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '@/ui/editable-field/states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '@/ui/editable-field/states/EditableFieldEntityIdContext';
import { EditableFieldMutationContext } from '@/ui/editable-field/states/EditableFieldMutationContext';
import {
Checkbox,
CheckboxVariant,
@ -167,27 +169,29 @@ export function CompanyBoardCard() {
</StyledCheckboxContainer>
</StyledBoardCardHeader>
<StyledBoardCardBody>
{viewFieldsDefinitions.map((viewField) => {
return (
<PreventSelectOnClickContainer key={viewField.id}>
<EditableFieldContext.Provider
value={{
entityId: boardCardId,
mutation: useUpdateOnePipelineProgressMutation,
fieldDefinition: {
id: viewField.id,
label: viewField.columnLabel,
icon: viewField.columnIcon,
type: viewField.metadata.type,
metadata: viewField.metadata,
},
}}
>
<GenericEditableField />
</EditableFieldContext.Provider>
</PreventSelectOnClickContainer>
);
})}
<EditableFieldMutationContext.Provider
value={useUpdateOnePipelineProgressMutation}
>
<EditableFieldEntityIdContext.Provider value={boardCardId}>
{viewFieldsDefinitions.map((viewField) => {
return (
<PreventSelectOnClickContainer key={viewField.id}>
<EditableFieldDefinitionContext.Provider
value={{
id: viewField.id,
label: viewField.columnLabel,
icon: viewField.columnIcon,
type: viewField.metadata.type,
metadata: viewField.metadata,
}}
>
<GenericEditableField />
</EditableFieldDefinitionContext.Provider>
</PreventSelectOnClickContainer>
);
})}
</EditableFieldEntityIdContext.Provider>
</EditableFieldMutationContext.Provider>
</StyledBoardCardBody>
</StyledBoardCard>
</StyledBoardCardWrapper>

View File

@ -1,24 +1,24 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { DateInputDisplay } from '@/ui/input/date/components/DateInputDisplay';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { parseDate } from '~/utils/date-utils';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { FieldContext } from '../states/FieldContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
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() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<FieldDateMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldDateMetadata>;
const fieldValue = useRecoilValue<string>(
genericEntityFieldFamilySelector({
@ -29,16 +29,12 @@ export function GenericEditableDateField() {
}),
);
const internalDateValue = fieldValue
? parseDate(fieldValue).toJSDate()
: null;
return (
<RecoilScope SpecificContext={FieldContext}>
<EditableField
iconLabel={currentEditableFieldDefinition.icon}
editModeContent={<GenericEditableDateFieldEditMode />}
displayModeContent={<DateInputDisplay value={internalDateValue} />}
displayModeContent={<GenericEditableDateFieldDisplayMode />}
isDisplayModeContentEmpty={!fieldValue}
/>
</RecoilScope>

View File

@ -0,0 +1,33 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { DateInputDisplay } from '@/ui/input/date/components/DateInputDisplay';
import { parseDate } from '~/utils/date-utils';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/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} />;
}

View File

@ -2,17 +2,18 @@ import { useContext } from 'react';
import { useRecoilState } from 'recoil';
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldDateMetadata } from '../types/FieldMetadata';
import { EditableFieldEditModeDate } from '../variants/components/EditableFieldEditModeDate';
export function GenericEditableDateFieldEditMode() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<FieldDateMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldDateMetadata>;
// TODO: we could use a hook that would return the field value with the right type
const [fieldValue, setFieldValue] = useRecoilState<string>(

View File

@ -1,6 +1,6 @@
import { useContext } from 'react';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { isFieldDate } from '../types/guards/isFieldDate';
import { isFieldNumber } from '../types/guards/isFieldNumber';
import { isFieldProbability } from '../types/guards/isFieldProbability';
@ -12,8 +12,7 @@ import { GenericEditableRelationField } from './GenericEditableRelationField';
import { ProbabilityEditableField } from './ProbabilityEditableField';
export function GenericEditableField() {
const currentEditableField = useContext(EditableFieldContext);
const fieldDefinition = currentEditableField.fieldDefinition;
const fieldDefinition = useContext(EditableFieldDefinitionContext);
if (isFieldRelation(fieldDefinition)) {
return <GenericEditableRelationField />;

View File

@ -3,7 +3,8 @@ import { useRecoilValue } from 'recoil';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { FieldContext } from '../states/FieldContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
@ -13,10 +14,10 @@ import { EditableField } from './EditableField';
import { GenericEditableNumberFieldEditMode } from './GenericEditableNumberFieldEditMode';
export function GenericEditableNumberField() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<FieldNumberMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldNumberMetadata>;
const fieldValue = useRecoilValue<string>(
genericEntityFieldFamilySelector({

View File

@ -9,16 +9,17 @@ import {
import { useRegisterCloseFieldHandlers } from '../hooks/useRegisterCloseFieldHandlers';
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldNumberMetadata } from '../types/FieldMetadata';
export function GenericEditableNumberFieldEditMode() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<FieldNumberMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldNumberMetadata>;
// TODO: we could use a hook that would return the field value with the right type
const [fieldValue, setFieldValue] = useRecoilState<number | null>(

View File

@ -1,51 +1,25 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { PersonChip } from '@/people/components/PersonChip';
import { ViewFieldRelationMetadata } from '@/ui/editable-field/types/ViewField';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { FieldContext } from '../states/FieldContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldRelationMetadata } from '../types/FieldMetadata';
import { EditableField } from './EditableField';
import { GenericEditableRelationFieldDisplayMode } from './GenericEditableRelationFieldDisplayMode';
import { GenericEditableRelationFieldEditMode } from './GenericEditableRelationFieldEditMode';
function RelationChip({
fieldDefinition,
fieldValue,
}: {
fieldDefinition: FieldDefinition<FieldRelationMetadata>;
fieldValue: any | null;
}) {
switch (fieldDefinition.metadata.relationType) {
case Entity.Person: {
return (
<PersonChip
id={fieldValue?.id ?? ''}
name={fieldValue?.displayName ?? ''}
pictureUrl={fieldValue?.avatarUrl ?? ''}
/>
);
}
default:
console.warn(
`Unknown relation type: "${fieldDefinition.metadata.relationType}" in GenericEditableRelationField`,
);
return <> </>;
}
}
export function GenericEditableRelationField() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<ViewFieldRelationMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldRelationMetadata>;
const fieldValue = useRecoilValue<any | null>(
genericEntityFieldFamilySelector({
@ -66,12 +40,7 @@ export function GenericEditableRelationField() {
}}
iconLabel={currentEditableFieldDefinition.icon}
editModeContent={<GenericEditableRelationFieldEditMode />}
displayModeContent={
<RelationChip
fieldDefinition={currentEditableFieldDefinition}
fieldValue={fieldValue}
/>
}
displayModeContent={<GenericEditableRelationFieldDisplayMode />}
isDisplayModeContentEmpty={!fieldValue}
isDisplayModeFixHeight
/>

View File

@ -0,0 +1,45 @@
import { useContext } from 'react';
import { useRecoilValue } from 'recoil';
import { PersonChip } from '@/people/components/PersonChip';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldRelationMetadata } from '../types/FieldMetadata';
export function GenericEditableRelationFieldDisplayMode() {
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldRelationMetadata>;
const fieldValue = useRecoilValue<any | null>(
genericEntityFieldFamilySelector({
entityId: currentEditableFieldEntityId ?? '',
fieldName: currentEditableFieldDefinition
? currentEditableFieldDefinition.metadata.fieldName
: '',
}),
);
switch (currentEditableFieldDefinition.metadata.relationType) {
case Entity.Person: {
return (
<PersonChip
id={fieldValue?.id ?? ''}
name={fieldValue?.displayName ?? ''}
pictureUrl={fieldValue?.avatarUrl ?? ''}
/>
);
}
default:
console.warn(
`Unknown relation type: "${currentEditableFieldDefinition.metadata.relationType}"
in GenericEditableRelationField`,
);
return <> </>;
}
}

View File

@ -3,16 +3,14 @@ import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { PeoplePicker } from '@/people/components/PeoplePicker';
import {
ViewFieldRelationMetadata,
ViewFieldRelationValue,
} from '@/ui/editable-field/types/ViewField';
import { ViewFieldRelationValue } from '@/ui/editable-field/types/ViewField';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useEditableField } from '../hooks/useEditableField';
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldRelationMetadata } from '../types/FieldMetadata';
@ -53,10 +51,10 @@ function RelationPicker({
}
export function GenericEditableRelationFieldEditMode() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<ViewFieldRelationMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldRelationMetadata>;
// TODO: we could use a hook that would return the field value with the right type
const [fieldValue, setFieldValue] = useRecoilState<any | null>(

View File

@ -4,13 +4,16 @@ import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldProbabilityMetadata } from '../types/FieldMetadata';
import { ProbabilityEditableFieldEditMode } from './ProbabilityEditableFieldEditMode';
export function ProbabilityEditableField() {
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldDefinition = currentEditableField.fieldDefinition;
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldProbabilityMetadata>;
return (
<RecoilScope SpecificContext={FieldContext}>

View File

@ -5,7 +5,8 @@ import { useRecoilState } from 'recoil';
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldDefinitionContext } from '../states/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../states/EditableFieldEntityIdContext';
import { genericEntityFieldFamilySelector } from '../states/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldProbabilityMetadata } from '../types/FieldMetadata';
@ -70,10 +71,10 @@ export function ProbabilityEditableFieldEditMode() {
const [nextProbabilityIndex, setNextProbabilityIndex] = useState<
number | null
>(null);
const currentEditableField = useContext(EditableFieldContext);
const currentEditableFieldEntityId = currentEditableField.entityId;
const currentEditableFieldDefinition =
currentEditableField.fieldDefinition as FieldDefinition<FieldProbabilityMetadata>;
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldProbabilityMetadata>;
const [fieldValue, setFieldValue] = useRecoilState<number>(
genericEntityFieldFamilySelector({

View File

@ -2,7 +2,7 @@ import { useContext } from 'react';
import { isFieldChip } from '@/ui/editable-field/types/guards/isFieldChip';
import { EditableFieldContext } from '../states/EditableFieldContext';
import { EditableFieldMutationContext } from '../states/EditableFieldMutationContext';
import { FieldDefinition } from '../types/FieldDefinition';
import {
FieldChipMetadata,
@ -48,8 +48,7 @@ import { isFieldURL } from '../types/guards/isFieldURL';
import { isFieldURLValue } from '../types/guards/isFieldURLValue';
export function useUpdateGenericEntityField() {
const currentEditableField = useContext(EditableFieldContext);
const useUpdateEntityMutation = currentEditableField?.mutation;
const useUpdateEntityMutation = useContext(EditableFieldMutationContext);
const [updateEntity] = useUpdateEntityMutation();

View File

@ -1,16 +0,0 @@
import { createContext } from 'react';
import { FieldDefinition } from '../types/FieldDefinition';
import { ViewFieldMetadata } from '../types/ViewField';
type EditableFieldContextValue = {
entityId: string;
fieldDefinition: FieldDefinition<ViewFieldMetadata>;
mutation: any;
};
export const EditableFieldContext = createContext<EditableFieldContextValue>({
entityId: '',
fieldDefinition: {} as FieldDefinition<ViewFieldMetadata>,
mutation: undefined,
});

View File

@ -0,0 +1,8 @@
import { createContext } from 'react';
import { FieldDefinition } from '../types/FieldDefinition';
import { ViewFieldMetadata } from '../types/ViewField';
export const EditableFieldDefinitionContext = createContext<
FieldDefinition<ViewFieldMetadata>
>({} as FieldDefinition<ViewFieldMetadata>);

View File

@ -1,3 +1,3 @@
import { createContext } from 'react';
export const EditableFieldEntityIdContext = createContext<string | null>(null);
export const EditableFieldEntityIdContext = createContext<string>('');

View File

@ -0,0 +1,3 @@
import { createContext } from 'react';
export const EditableFieldMutationContext = createContext<any>(undefined);