Chore: New standard fields on Companies (#1276)

* New standard fields on Companies

Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

* New standard fields on Companies

Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

* Add requested changes

Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

* Make some fields hidden by default

Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

* Add minor refactors

Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>

---------

Co-authored-by: Thiago Nascimbeni <tnascimbeni@gmail.com>
Co-authored-by: Matheus <matheus_benini@hotmail.com>
Co-authored-by: v1b3m <vibenjamin6@gmail.com>
This commit is contained in:
gitstart-twenty
2023-08-24 15:36:12 +00:00
committed by GitHub
parent 615018654a
commit baf92d6d65
21 changed files with 420 additions and 9 deletions

View File

@ -1,6 +1,8 @@
import { isViewFieldBoolean } from '@/ui/editable-field/types/guards/isViewFieldBoolean';
import { isViewFieldDate } from '@/ui/editable-field/types/guards/isViewFieldDate';
import { isViewFieldDoubleText } from '@/ui/editable-field/types/guards/isViewFieldDoubleText';
import { isViewFieldDoubleTextChip } from '@/ui/editable-field/types/guards/isViewFieldDoubleTextChip';
import { isViewFieldMoney } from '@/ui/editable-field/types/guards/isViewFieldMoney';
import { isViewFieldNumber } from '@/ui/editable-field/types/guards/isViewFieldNumber';
import { isViewFieldPhone } from '@/ui/editable-field/types/guards/isViewFieldPhone';
import { isViewFieldRelation } from '@/ui/editable-field/types/guards/isViewFieldRelation';
@ -12,10 +14,12 @@ import {
} from '@/ui/editable-field/types/ViewField';
import { isViewFieldChip } from '../../../editable-field/types/guards/isViewFieldChip';
import { GenericEditableBooleanCell } from '../type/components/GenericEditableBooleanCell';
import { GenericEditableChipCell } from '../type/components/GenericEditableChipCell';
import { GenericEditableDateCell } from '../type/components/GenericEditableDateCell';
import { GenericEditableDoubleTextCell } from '../type/components/GenericEditableDoubleTextCell';
import { GenericEditableDoubleTextChipCell } from '../type/components/GenericEditableDoubleTextChipCell';
import { GenericEditableMoneyCell } from '../type/components/GenericEditableMoneyCell';
import { GenericEditableNumberCell } from '../type/components/GenericEditableNumberCell';
import { GenericEditablePhoneCell } from '../type/components/GenericEditablePhoneCell';
import { GenericEditableRelationCell } from '../type/components/GenericEditableRelationCell';
@ -43,8 +47,12 @@ export function GenericEditableCell({ viewField: fieldDefinition }: OwnProps) {
return <GenericEditableDateCell viewField={fieldDefinition} />;
} else if (isViewFieldNumber(fieldDefinition)) {
return <GenericEditableNumberCell viewField={fieldDefinition} />;
} else if (isViewFieldBoolean(fieldDefinition)) {
return <GenericEditableBooleanCell viewField={fieldDefinition} />;
} else if (isViewFieldChip(fieldDefinition)) {
return <GenericEditableChipCell viewField={fieldDefinition} />;
} else if (isViewFieldMoney(fieldDefinition)) {
return <GenericEditableMoneyCell viewField={fieldDefinition} />;
} else {
console.warn(
`Unknown field metadata type: ${fieldDefinition.metadata.type} in GenericEditableCell`,

View File

@ -0,0 +1,77 @@
import styled from '@emotion/styled';
import { IconCheck, IconX } from '@tabler/icons-react';
import { useRecoilState } from 'recoil';
import {
ViewFieldBooleanMetadata,
ViewFieldDefinition,
} from '@/ui/editable-field/types/ViewField';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
import { EditableCellDisplayContainer } from '../../components/EditableCellContainer';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldBooleanMetadata>;
editModeHorizontalAlign?: 'left' | 'right';
};
const StyledCellBaseContainer = styled.div`
align-items: center;
box-sizing: border-box;
cursor: pointer;
display: flex;
height: ${({ theme }) => theme.spacing(8)};
position: relative;
user-select: none;
width: 100%;
`;
const StyledCellBooleancontainer = styled.div`
margin-left: 5px;
`;
function capitalizeFirstLetter(value: string) {
return value.charAt(0).toUpperCase() + value.slice(1);
}
export function GenericEditableBooleanCell({ viewField }: OwnProps) {
const currentRowEntityId = useCurrentRowEntityId();
const [fieldValue, setFieldValue] = useRecoilState<boolean>(
tableEntityFieldFamilySelector({
entityId: currentRowEntityId ?? '',
fieldName: viewField.metadata.fieldName,
}),
);
const updateField = useUpdateEntityField();
function handleClick() {
const newValue = !fieldValue;
try {
setFieldValue(newValue);
if (currentRowEntityId && updateField) {
updateField(currentRowEntityId, viewField, newValue);
}
} catch (error) {
console.warn(
`In GenericEditableBooleanCellEditMode, Invalid value: ${newValue}, ${error}`,
);
}
}
return (
<StyledCellBaseContainer>
<EditableCellDisplayContainer onClick={handleClick}>
{fieldValue ? <IconCheck /> : <IconX />}
<StyledCellBooleancontainer>
{fieldValue !== undefined &&
capitalizeFirstLetter(fieldValue.toString())}
</StyledCellBooleancontainer>
</EditableCellDisplayContainer>
</StyledCellBaseContainer>
);
}

View File

@ -0,0 +1,47 @@
import { useRecoilValue } from 'recoil';
import {
ViewFieldDefinition,
ViewFieldMoneyMetadata,
} from '@/ui/editable-field/types/ViewField';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
import { GenericEditableMoneyCellEditMode } from './GenericEditableMoneyCellEditMode';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldMoneyMetadata>;
editModeHorizontalAlign?: 'left' | 'right';
};
function formatNumber(value: number) {
// Formats the value to a string and add commas to it ex: 50,000 | 500,000
return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}
export function GenericEditableMoneyCell({
viewField,
editModeHorizontalAlign,
}: OwnProps) {
const currentRowEntityId = useCurrentRowEntityId();
const fieldValue = useRecoilValue<number>(
tableEntityFieldFamilySelector({
entityId: currentRowEntityId ?? '',
fieldName: viewField.metadata.fieldName,
}),
);
return (
<EditableCell
editModeHorizontalAlign={editModeHorizontalAlign}
editModeContent={
<GenericEditableMoneyCellEditMode viewField={viewField} />
}
nonEditModeContent={
<>{fieldValue ? `$${formatNumber(fieldValue)}` : ''}</>
}
></EditableCell>
);
}

View File

@ -0,0 +1,58 @@
import { useRecoilState } from 'recoil';
import {
ViewFieldDefinition,
ViewFieldMoneyMetadata,
} from '@/ui/editable-field/types/ViewField';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/selectors/tableEntityFieldFamilySelector';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldMoneyMetadata>;
};
export function GenericEditableMoneyCellEditMode({ viewField }: OwnProps) {
const currentRowEntityId = useCurrentRowEntityId();
const [fieldValue, setFieldValue] = useRecoilState<string>(
tableEntityFieldFamilySelector({
entityId: currentRowEntityId ?? '',
fieldName: viewField.metadata.fieldName,
}),
);
const updateField = useUpdateEntityField();
function handleSubmit(newText: string) {
if (newText === fieldValue) return;
try {
const numberValue = parseInt(newText);
if (isNaN(numberValue)) {
throw new Error('Not a number');
}
if (numberValue > 2000000000) {
throw new Error('Number too big');
}
setFieldValue(numberValue.toString());
if (currentRowEntityId && updateField) {
updateField(currentRowEntityId, viewField, numberValue);
}
} catch (error) {
console.warn(
`In GenericEditableMoneyCellEditMode, Invalid number: ${newText}, ${error}`,
);
}
}
return (
<TextCellEdit autoFocus value={fieldValue ?? ''} onSubmit={handleSubmit} />
);
}

View File

@ -1,5 +1,7 @@
import { useContext } from 'react';
import { isViewFieldBoolean } from '@/ui/editable-field/types/guards/isViewFieldBoolean';
import { isViewFieldBooleanValue } from '@/ui/editable-field/types/guards/isViewFieldBooleanValue';
import { isViewFieldChip } from '@/ui/editable-field/types/guards/isViewFieldChip';
import { isViewFieldDate } from '@/ui/editable-field/types/guards/isViewFieldDate';
import { isViewFieldDateValue } from '@/ui/editable-field/types/guards/isViewFieldDateValue';
@ -7,6 +9,8 @@ import { isViewFieldDoubleText } from '@/ui/editable-field/types/guards/isViewFi
import { isViewFieldDoubleTextChip } from '@/ui/editable-field/types/guards/isViewFieldDoubleTextChip';
import { isViewFieldDoubleTextChipValue } from '@/ui/editable-field/types/guards/isViewFieldDoubleTextChipValue';
import { isViewFieldDoubleTextValue } from '@/ui/editable-field/types/guards/isViewFieldDoubleTextValue';
import { isViewFieldMoney } from '@/ui/editable-field/types/guards/isViewFieldMoney';
import { isViewFieldMoneyValue } from '@/ui/editable-field/types/guards/isViewFieldMoneyValue';
import { isViewFieldNumber } from '@/ui/editable-field/types/guards/isViewFieldNumber';
import { isViewFieldNumberValue } from '@/ui/editable-field/types/guards/isViewFieldNumberValue';
import { isViewFieldPhone } from '@/ui/editable-field/types/guards/isViewFieldPhone';
@ -202,6 +206,32 @@ export function useUpdateEntityField() {
) {
const newContent = newFieldValueUnknown;
updateEntity({
variables: {
where: { id: currentEntityId },
data: { [viewField.metadata.fieldName]: newContent },
},
});
// Boolean
} else if (
isViewFieldBoolean(viewField) &&
isViewFieldBooleanValue(newFieldValueUnknown)
) {
const newContent = newFieldValueUnknown;
updateEntity({
variables: {
where: { id: currentEntityId },
data: { [viewField.metadata.fieldName]: newContent },
},
});
// Money
} else if (
isViewFieldMoney(viewField) &&
isViewFieldMoneyValue(newFieldValueUnknown)
) {
const newContent = newFieldValueUnknown;
updateEntity({
variables: {
where: { id: currentEntityId },