mirror of
https://github.com/twentyhq/twenty.git
synced 2024-12-24 20:42:05 +03:00
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:
parent
88915291d9
commit
ea7d52fba8
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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 && (
|
||||
|
Loading…
Reference in New Issue
Block a user