feature to reset value in select field (#6067)

Fixes #6064 



https://github.com/twentyhq/twenty/assets/55168611/8c553422-6ad2-4e6b-bd00-962dd81c0a93

---------

Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
Sudarsh 2024-07-02 16:46:17 +05:30 committed by GitHub
parent 88915291d9
commit ea7d52fba8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 45 additions and 7 deletions

View File

@ -2,6 +2,7 @@ import { useContext } from 'react';
import { useRecoilCallback } from 'recoil';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { useSetRecordFieldValue } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { generateEmptyFieldValue } from '@/object-record/utils/generateEmptyFieldValue';
@ -16,6 +17,8 @@ export const useClearField = () => {
const [updateRecord] = useUpdateRecord();
const setRecordFieldValue = useSetRecordFieldValue();
const clearField = useRecoilCallback(
({ snapshot, set }) =>
() => {
@ -46,6 +49,8 @@ export const useClearField = () => {
emptyFieldValue,
);
setRecordFieldValue(entityId, fieldName, emptyFieldValue);
updateRecord?.({
variables: {
where: { id: entityId },
@ -55,7 +60,7 @@ export const useClearField = () => {
},
});
},
[entityId, fieldDefinition, updateRecord],
[entityId, fieldDefinition, updateRecord, setRecordFieldValue],
);
return clearField;

View File

@ -2,6 +2,7 @@ import React, { useRef, useState } from 'react';
import styled from '@emotion/styled';
import { Key } from 'ts-key-enum';
import { useClearField } from '@/object-record/record-field/hooks/useClearField';
import { useSelectField } from '@/object-record/record-field/meta-types/hooks/useSelectField';
import { FieldInputEvent } from '@/object-record/record-field/types/FieldInputEvent';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
@ -30,12 +31,15 @@ export const SelectFieldInput = ({
}: SelectFieldInputProps) => {
const { persistField, fieldDefinition, fieldValue, hotkeyScope } =
useSelectField();
const clearField = useClearField();
const [searchFilter, setSearchFilter] = useState('');
const containerRef = useRef<HTMLDivElement>(null);
const selectedOption = fieldDefinition.metadata.options.find(
(option) => option.value === fieldValue,
);
const optionsToSelect =
fieldDefinition.metadata.options.filter((option) => {
return (
@ -43,10 +47,17 @@ export const SelectFieldInput = ({
option.label.toLowerCase().includes(searchFilter.toLowerCase())
);
}) || [];
const optionsInDropDown = selectedOption
? [selectedOption, ...optionsToSelect]
: optionsToSelect;
// handlers
const handleClearField = () => {
clearField();
onCancel?.();
};
useListenClickOutside({
refs: [containerRef],
callback: (event) => {
@ -85,7 +96,17 @@ export const SelectFieldInput = ({
autoFocus
/>
<DropdownMenuSeparator />
<DropdownMenuItemsContainer hasMaxHeight>
<MenuItemSelectTag
key={`No ${fieldDefinition.label}`}
selected={false}
text={`No ${fieldDefinition.label}`}
color="transparent"
variant="outline"
onClick={handleClearField}
/>
{optionsInDropDown.map((option) => {
return (
<MenuItemSelectTag

View File

@ -9,8 +9,9 @@ type MenuItemSelectTagProps = {
selected: boolean;
className?: string;
onClick?: () => void;
color: ThemeColor;
color: ThemeColor | 'transparent';
text: string;
variant?: 'solid' | 'outline';
};
export const MenuItemSelectTag = ({
@ -19,6 +20,7 @@ export const MenuItemSelectTag = ({
className,
onClick,
text,
variant = 'solid',
}: MenuItemSelectTagProps) => {
const theme = useTheme();
@ -29,7 +31,7 @@ export const MenuItemSelectTag = ({
selected={selected}
>
<StyledMenuItemLeftContent>
<Tag color={color} text={text} />
<Tag variant={variant} color={color} text={text} />
</StyledMenuItemLeftContent>
{selected && <IconCheck size={theme.icon.size.sm} />}
</StyledMenuItemSelect>

View File

@ -16,14 +16,17 @@ const spacing1 = THEME_COMMON.spacing(1);
const StyledTag = styled.h3<{
theme: ThemeType;
color: ThemeColor;
color: TagColor;
weight: TagWeight;
variant: TagVariant;
preventShrink?: boolean;
}>`
align-items: center;
background: ${({ color, theme }) => theme.tag.background[color]};
background: ${({ color, theme }) =>
color === 'transparent' ? color : theme.tag.background[color]};
border-radius: ${BORDER_COMMON.radius.sm};
color: ${({ color, theme }) => theme.tag.text[color]};
color: ${({ color, theme }) =>
color === 'transparent' ? theme.tag.text['gray'] : theme.tag.text[color]};
display: inline-flex;
font-size: ${({ theme }) => theme.font.size.md};
font-style: normal;
@ -35,6 +38,8 @@ const StyledTag = styled.h3<{
margin: 0;
overflow: hidden;
padding: 0 ${spacing2};
border: ${({ variant, theme }) =>
variant === 'outline' ? `2px dashed ${theme.tag.background['gray']}` : ''};
gap: ${spacing1};
@ -58,14 +63,17 @@ const StyledIconContainer = styled.div`
`;
type TagWeight = 'regular' | 'medium';
type TagVariant = 'solid' | 'outline';
type TagColor = ThemeColor | 'transparent';
type TagProps = {
className?: string;
color: ThemeColor;
color: TagColor;
text: string;
Icon?: IconComponent;
onClick?: () => void;
weight?: TagWeight;
variant?: TagVariant;
preventShrink?: boolean;
};
@ -77,6 +85,7 @@ export const Tag = ({
Icon,
onClick,
weight = 'regular',
variant = 'solid',
preventShrink,
}: TagProps) => {
const { theme } = useContext(ThemeContext);
@ -88,6 +97,7 @@ export const Tag = ({
color={color}
onClick={onClick}
weight={weight}
variant={variant}
preventShrink={preventShrink}
>
{!!Icon && (