Add idealCustomerProfile to company show page (#1312)

* Add idealCustomerProfile to company show page

* remove editMode

* add xUrl
This commit is contained in:
Weiko
2023-08-25 21:11:43 +02:00
committed by GitHub
parent 67cf6cd7e2
commit 8a3a176571
8 changed files with 169 additions and 1 deletions

View File

@ -0,0 +1,27 @@
import { useContext } from 'react';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
import { FieldRecoilScopeContext } from '../states/recoil-scope-contexts/FieldRecoilScopeContext';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldBooleanMetadata } from '../types/FieldMetadata';
import { EditableField } from './EditableField';
import { GenericEditableBooleanFieldDisplayMode } from './GenericEditableBooleanFieldDisplayMode';
export function GenericEditableBooleanField() {
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldBooleanMetadata>;
return (
<RecoilScope SpecificContext={FieldRecoilScopeContext}>
<EditableField
iconLabel={currentEditableFieldDefinition.icon}
displayModeContent={<GenericEditableBooleanFieldDisplayMode />}
displayModeContentOnly
/>
</RecoilScope>
);
}

View File

@ -0,0 +1,69 @@
import { useContext } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRecoilState } from 'recoil';
import { IconCheck, IconX } from '@/ui/icon';
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
import { EditableFieldEntityIdContext } from '../contexts/EditableFieldEntityIdContext';
import { useUpdateGenericEntityField } from '../hooks/useUpdateGenericEntityField';
import { genericEntityFieldFamilySelector } from '../states/selectors/genericEntityFieldFamilySelector';
import { FieldDefinition } from '../types/FieldDefinition';
import { FieldBooleanMetadata } from '../types/FieldMetadata';
const StyledEditableBooleanFieldContainer = styled.div`
cursor: pointer;
display: flex;
`;
const StyledBooleanFieldIcon = styled.div``;
const StyledEditableBooleanFieldValue = styled.div`
margin-left: ${({ theme }) => theme.spacing(1)};
`;
export function GenericEditableBooleanFieldDisplayMode() {
const currentEditableFieldEntityId = useContext(EditableFieldEntityIdContext);
const currentEditableFieldDefinition = useContext(
EditableFieldDefinitionContext,
) as FieldDefinition<FieldBooleanMetadata>;
const [fieldValue, setFieldValue] = useRecoilState<boolean>(
genericEntityFieldFamilySelector({
entityId: currentEditableFieldEntityId ?? '',
fieldName: currentEditableFieldDefinition
? currentEditableFieldDefinition.metadata.fieldName
: '',
}),
);
const theme = useTheme();
const updateField = useUpdateGenericEntityField();
function toggleValue() {
const newToggledValue = !fieldValue;
setFieldValue(newToggledValue);
if (currentEditableFieldEntityId && updateField) {
updateField(
currentEditableFieldEntityId,
currentEditableFieldDefinition,
newToggledValue,
);
}
}
return (
<StyledEditableBooleanFieldContainer onClick={toggleValue}>
<StyledBooleanFieldIcon>
{fieldValue ? (
<IconCheck size={theme.icon.size.sm} />
) : (
<IconX size={theme.icon.size.sm} />
)}
</StyledBooleanFieldIcon>
<StyledEditableBooleanFieldValue>
{fieldValue ? 'True' : 'False'}
</StyledEditableBooleanFieldValue>
</StyledEditableBooleanFieldContainer>
);
}

View File

@ -1,6 +1,7 @@
import { useContext } from 'react';
import { EditableFieldDefinitionContext } from '../contexts/EditableFieldDefinitionContext';
import { isFieldBoolean } from '../types/guards/isFieldBoolean';
import { isFieldDate } from '../types/guards/isFieldDate';
import { isFieldNumber } from '../types/guards/isFieldNumber';
import { isFieldPhone } from '../types/guards/isFieldPhone';
@ -9,6 +10,7 @@ import { isFieldRelation } from '../types/guards/isFieldRelation';
import { isFieldText } from '../types/guards/isFieldText';
import { isFieldURL } from '../types/guards/isFieldURL';
import { GenericEditableBooleanField } from './GenericEditableBooleanField';
import { GenericEditableDateField } from './GenericEditableDateField';
import { GenericEditableNumberField } from './GenericEditableNumberField';
import { GenericEditablePhoneField } from './GenericEditablePhoneField';
@ -34,6 +36,8 @@ export function GenericEditableField() {
return <GenericEditableTextField />;
} else if (isFieldPhone(fieldDefinition)) {
return <GenericEditablePhoneField />;
} else if (isFieldBoolean(fieldDefinition)) {
return <GenericEditableBooleanField />;
} else {
console.warn(
`Unknown field metadata type: ${fieldDefinition.type} in GenericEditableField`,

View File

@ -3,6 +3,8 @@ import { useContext } from 'react';
import { EditableFieldMutationContext } from '../contexts/EditableFieldMutationContext';
import { FieldDefinition } from '../types/FieldDefinition';
import {
FieldBooleanMetadata,
FieldBooleanValue,
FieldChipMetadata,
FieldChipValue,
FieldDateMetadata,
@ -25,6 +27,8 @@ import {
FieldURLMetadata,
FieldURLValue,
} from '../types/FieldMetadata';
import { isFieldBoolean } from '../types/guards/isFieldBoolean';
import { isFieldBooleanValue } from '../types/guards/isFieldBooleanValue';
import { isFieldChip } from '../types/guards/isFieldChip';
import { isFieldChipValue } from '../types/guards/isFieldChipValue';
import { isFieldDate } from '../types/guards/isFieldDate';
@ -72,6 +76,8 @@ export function useUpdateGenericEntityField() {
? FieldRelationValue
: FieldMetadata extends FieldProbabilityMetadata
? FieldProbabilityValue
: FieldMetadata extends FieldBooleanMetadata
? FieldBooleanValue
: unknown,
>(
currentEntityId: string,
@ -215,6 +221,20 @@ export function useUpdateGenericEntityField() {
) {
const newContent = newFieldValueUnknown;
updateEntity({
variables: {
where: { id: currentEntityId },
data: { [field.metadata.fieldName]: newContent },
},
});
}
// Boolean
else if (
isFieldBoolean(field) &&
isFieldBooleanValue(newFieldValueUnknown)
) {
const newContent = newFieldValueUnknown;
updateEntity({
variables: {
where: { id: currentEntityId },

View File

@ -79,6 +79,10 @@ export type FieldProbabilityMetadata = {
fieldName: string;
};
export type FieldBooleanMetadata = {
fieldName: string;
};
export type FieldMetadata =
| FieldTextMetadata
| FieldRelationMetadata
@ -90,7 +94,8 @@ export type FieldMetadata =
| FieldNumberMetadata
| FieldEmailMetadata
| FieldDateMetadata
| FieldProbabilityMetadata;
| FieldProbabilityMetadata
| FieldBooleanMetadata;
export type FieldTextValue = string;
@ -101,6 +106,7 @@ export type FieldURLValue = string;
export type FieldNumberValue = number | null;
export type FieldEmailValue = string;
export type FieldProbabilityValue = number;
export type FieldBooleanValue = boolean;
export type FieldDoubleTextValue = {
firstValue: string;

View File

@ -0,0 +1,8 @@
import { FieldDefinition } from '../FieldDefinition';
import { FieldBooleanMetadata, FieldMetadata } from '../FieldMetadata';
export function isFieldBoolean(
field: FieldDefinition<FieldMetadata>,
): field is FieldDefinition<FieldBooleanMetadata> {
return field.type === 'boolean';
}

View File

@ -0,0 +1,12 @@
import { FieldBooleanValue } from '../FieldMetadata';
// TODO: add yup
export function isFieldBooleanValue(
fieldValue: unknown,
): fieldValue is FieldBooleanValue {
return (
fieldValue !== null &&
fieldValue !== undefined &&
typeof fieldValue === 'boolean'
);
}

View File

@ -1,5 +1,6 @@
import { FieldDefinition } from '@/ui/editable-field/types/FieldDefinition';
import {
FieldBooleanMetadata,
FieldDateMetadata,
FieldMetadata,
FieldNumberMetadata,
@ -8,9 +9,11 @@ import {
FieldURLMetadata,
} from '@/ui/editable-field/types/FieldMetadata';
import {
IconBrandX,
IconCalendar,
IconLink,
IconMap,
IconTarget,
IconUserCircle,
IconUsers,
} from '@/ui/icon';
@ -66,4 +69,23 @@ export const companyShowFieldDefinition: FieldDefinition<FieldMetadata>[] = [
fieldName: 'createdAt',
},
} satisfies FieldDefinition<FieldDateMetadata>,
{
id: 'idealCustomerProfile',
label: 'ICP',
icon: <IconTarget />,
type: 'boolean',
metadata: {
fieldName: 'idealCustomerProfile',
},
} satisfies FieldDefinition<FieldBooleanMetadata>,
{
id: 'xUrl',
label: 'Twitter',
icon: <IconBrandX />,
type: 'url',
metadata: {
fieldName: 'xUrl',
placeHolder: 'X',
},
} satisfies FieldDefinition<FieldURLMetadata>,
];