diff --git a/front/src/modules/companies/components/CompanyEditableNameCell.tsx b/front/src/modules/companies/components/CompanyEditableNameCell.tsx index 20327a07a..c2b9fd3ac 100644 --- a/front/src/modules/companies/components/CompanyEditableNameCell.tsx +++ b/front/src/modules/companies/components/CompanyEditableNameCell.tsx @@ -1,6 +1,6 @@ import { CellCommentChip } from '@/comments/components/CellCommentChip'; import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer'; -import EditableChip from '@/ui/components/editable-cell/types/EditableChip'; +import { EditableCellChip } from '@/ui/components/editable-cell/types/EditableChip'; import { getLogoUrlFromDomainName } from '@/utils/utils'; import { CommentableType, @@ -34,7 +34,7 @@ export function CompanyEditableNameChipCell({ company }: OwnProps) { } return ( - { + setBoardItems(initialItems); + }, [initialItems, setBoardItems]); + useEffect(() => { if (isInitialBoardLoaded) return; setBoard(initialBoard); diff --git a/front/src/modules/pipeline-progress/components/CompanyBoardCard.tsx b/front/src/modules/pipeline-progress/components/CompanyBoardCard.tsx index 903a9e579..254f26fe4 100644 --- a/front/src/modules/pipeline-progress/components/CompanyBoardCard.tsx +++ b/front/src/modules/pipeline-progress/components/CompanyBoardCard.tsx @@ -2,11 +2,8 @@ import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { IconCurrencyDollar } from '@tabler/icons-react'; -import { RecoilScope } from '@/recoil-scope/components/RecoilScope'; -import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate'; -import { EditableText } from '@/ui/components/editable-cell/types/EditableText'; -import { CellContext } from '@/ui/tables/states/CellContext'; -import { RowContext } from '@/ui/tables/states/RowContext'; +import { BoardCardEditableFieldDate } from '@/ui/board-card-field-inputs/components/BoardCardEditableFieldDate'; +import { BoardCardEditableFieldText } from '@/ui/board-card-field-inputs/components/BoardCardEditableFieldText'; import { Company, PipelineProgress } from '../../../generated/graphql'; import { Checkbox } from '../../ui/components/form/Checkbox'; @@ -72,17 +69,6 @@ type PipelineProgressProp = Pick< 'id' | 'amount' | 'closeDate' >; -// TODO: Remove when refactoring EditableCell into EditableField -function HackScope({ children }: { children: React.ReactNode }) { - return ( - - - {children} - - - ); -} - export function CompanyBoardCard({ company, pipelineProgress, @@ -112,32 +98,28 @@ export function CompanyBoardCard({ - - - onCardUpdate({ - ...pipelineProgress, - amount: parseInt(value), - }) - } - /> - + + onCardUpdate({ + ...pipelineProgress, + amount: parseInt(value), + }) + } + /> - - { - onCardUpdate({ - ...pipelineProgress, - closeDate: value.toISOString(), - }); - }} - /> - + { + onCardUpdate({ + ...pipelineProgress, + closeDate: value.toISOString(), + }); + }} + /> diff --git a/front/src/modules/pipeline-progress/components/NewButton.tsx b/front/src/modules/pipeline-progress/components/NewButton.tsx index e4da7c508..d7c3d8bfb 100644 --- a/front/src/modules/pipeline-progress/components/NewButton.tsx +++ b/front/src/modules/pipeline-progress/components/NewButton.tsx @@ -3,8 +3,8 @@ import { useRecoilState } from 'recoil'; import { v4 as uuidv4 } from 'uuid'; import { RecoilScope } from '@/recoil-scope/components/RecoilScope'; -import { Column } from '@/ui/components/board/Board'; -import { NewButton as UINewButton } from '@/ui/components/board/NewButton'; +import { Column } from '@/ui/board/components/Board'; +import { NewButton as UINewButton } from '@/ui/board/components/NewButton'; import { Company, PipelineProgressableType, diff --git a/front/src/modules/pipeline-progress/components/__stories__/mock-data.ts b/front/src/modules/pipeline-progress/components/__stories__/mock-data.ts index 15e52739e..f237c0e44 100644 --- a/front/src/modules/pipeline-progress/components/__stories__/mock-data.ts +++ b/front/src/modules/pipeline-progress/components/__stories__/mock-data.ts @@ -1,4 +1,4 @@ -import { Column } from '@/ui/components/board/Board'; +import { Column } from '@/ui/board/components/Board'; import { mockedCompaniesData } from '~/testing/mock-data/companies'; import { CompanyProgressDict } from '../Board'; diff --git a/front/src/modules/pipeline-progress/hooks/useBoard.ts b/front/src/modules/pipeline-progress/hooks/useBoard.ts index e38677d6d..d927221e2 100644 --- a/front/src/modules/pipeline-progress/hooks/useBoard.ts +++ b/front/src/modules/pipeline-progress/hooks/useBoard.ts @@ -4,7 +4,7 @@ import { useGetCompaniesQuery, useGetPipelinesQuery, } from '../../../generated/graphql'; -import { Column } from '../../ui/components/board/Board'; +import { Column } from '../../ui/board/components/Board'; type ItemCompany = Pick; type ItemPipelineProgress = Pick< diff --git a/front/src/modules/pipeline-progress/states/boardColumnsState.ts b/front/src/modules/pipeline-progress/states/boardColumnsState.ts index eb48df9ca..90f823417 100644 --- a/front/src/modules/pipeline-progress/states/boardColumnsState.ts +++ b/front/src/modules/pipeline-progress/states/boardColumnsState.ts @@ -1,6 +1,6 @@ import { atom } from 'recoil'; -import { Column } from '@/ui/components/board/Board'; +import { Column } from '@/ui/board/components/Board'; export const boardColumnsState = atom({ key: 'boardColumnsState', diff --git a/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDate.tsx b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDate.tsx new file mode 100644 index 000000000..fcd98724b --- /dev/null +++ b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDate.tsx @@ -0,0 +1,26 @@ +import { BoardCardEditableField } from '@/ui/board-card-field/components/BoardCardEditableField'; +import { InplaceInputDateDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputDateDisplayMode'; + +import { BoardCardEditableFieldDateEditMode } from './BoardCardEditableFieldDateEditMode'; + +type OwnProps = { + value: Date; + onChange: (newValue: Date) => void; + editModeHorizontalAlign?: 'left' | 'right'; +}; + +export function BoardCardEditableFieldDate({ + value, + onChange, + editModeHorizontalAlign, +}: OwnProps) { + return ( + + } + nonEditModeContent={} + > + ); +} diff --git a/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDateEditMode.tsx b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDateEditMode.tsx new file mode 100644 index 000000000..16b1c3833 --- /dev/null +++ b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldDateEditMode.tsx @@ -0,0 +1,21 @@ +import { useBoardCardField } from '@/ui/board-card-field/hooks/useBoardCardField'; +import { InplaceInputDateEditMode } from '@/ui/inplace-inputs/components/InplaceInputDateEditMode'; + +type OwnProps = { + value: Date; + onChange: (newValue: Date) => void; +}; + +export function BoardCardEditableFieldDateEditMode({ + value, + onChange, +}: OwnProps) { + const { closeBoardCardField } = useBoardCardField(); + + function handleDateChange(newDate: Date) { + onChange(newDate); + closeBoardCardField(); + } + + return ; +} diff --git a/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldText.tsx b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldText.tsx new file mode 100644 index 000000000..8d062fa91 --- /dev/null +++ b/front/src/modules/ui/board-card-field-inputs/components/BoardCardEditableFieldText.tsx @@ -0,0 +1,38 @@ +import { ChangeEvent } from 'react'; + +import { BoardCardEditableField } from '@/ui/board-card-field/components/BoardCardEditableField'; +import { InplaceInputTextDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputTextDisplayMode'; +import { InplaceInputTextEditMode } from '@/ui/inplace-inputs/components/InplaceInputTextEditMode'; + +type OwnProps = { + placeholder?: string; + value: string; + onChange: (newValue: string) => void; + editModeHorizontalAlign?: 'left' | 'right'; +}; + +export function BoardCardEditableFieldText({ + value, + placeholder, + onChange, + editModeHorizontalAlign, +}: OwnProps) { + return ( + ) => { + onChange(event.target.value); + }} + /> + } + nonEditModeContent={ + {value} + } + > + ); +} diff --git a/front/src/modules/ui/board-card-field/components/BoardCardEditableField.tsx b/front/src/modules/ui/board-card-field/components/BoardCardEditableField.tsx new file mode 100644 index 000000000..e3576f2ae --- /dev/null +++ b/front/src/modules/ui/board-card-field/components/BoardCardEditableField.tsx @@ -0,0 +1,24 @@ +import { ReactElement } from 'react'; + +import { HotkeysScopeStackItem } from '@/hotkeys/types/internal/HotkeysScopeStackItems'; +import { RecoilScope } from '@/recoil-scope/components/RecoilScope'; + +import { BoardCardFieldContext } from '../states/BoardCardFieldContext'; + +import { BoardCardEditableFieldInternal } from './BoardCardEditableFieldInternal'; + +type OwnProps = { + editModeContent: ReactElement; + nonEditModeContent: ReactElement; + editModeHorizontalAlign?: 'left' | 'right'; + editModeVerticalPosition?: 'over' | 'below'; + editHotkeysScope?: HotkeysScopeStackItem; +}; + +export function BoardCardEditableField(props: OwnProps) { + return ( + + + + ); +} diff --git a/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldDisplayMode.tsx b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldDisplayMode.tsx new file mode 100644 index 000000000..a3dfce28d --- /dev/null +++ b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldDisplayMode.tsx @@ -0,0 +1,32 @@ +import styled from '@emotion/styled'; + +export const BoardCardFieldDisplayModeOuterContainer = styled.div` + align-items: center; + display: flex; + height: 100%; + overflow: hidden; + + padding-left: ${({ theme }) => theme.spacing(2)}; + padding-right: ${({ theme }) => theme.spacing(1)}; + width: 100%; +`; + +export const BoardCardFieldDisplayModeInnerContainer = styled.div` + align-items: center; + display: flex; + height: 100%; + overflow: hidden; + width: 100%; +`; + +export function BoardCardEditableFieldDisplayMode({ + children, +}: React.PropsWithChildren) { + return ( + + + {children} + + + ); +} diff --git a/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldEditMode.tsx b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldEditMode.tsx new file mode 100644 index 000000000..97998219b --- /dev/null +++ b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldEditMode.tsx @@ -0,0 +1,78 @@ +import { ReactElement, useRef } from 'react'; +import styled from '@emotion/styled'; + +import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys'; +import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope'; +import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef'; +import { overlayBackground } from '@/ui/themes/effects'; + +import { useBoardCardField } from '../hooks/useBoardCardField'; + +export const BoardCardFieldEditModeContainer = styled.div` + align-items: center; + border: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: ${({ theme }) => theme.border.radius.sm}; + display: flex; + left: ${(props) => + props.editModeHorizontalAlign === 'right' ? 'auto' : '0'}; + margin-left: -2px; + min-height: 100%; + min-width: calc(100% + 20px); + position: absolute; + + right: ${(props) => + props.editModeHorizontalAlign === 'right' ? '0' : 'auto'}; + top: ${(props) => (props.editModeVerticalPosition === 'over' ? '0' : '100%')}; + z-index: 1; + ${overlayBackground} +`; + +type OwnProps = { + children: ReactElement; + editModeHorizontalAlign?: 'left' | 'right'; + editModeVerticalPosition?: 'over' | 'below'; + onOutsideClick?: () => void; +}; + +export function BoardCardEditableFieldEditMode({ + editModeHorizontalAlign, + editModeVerticalPosition, + children, +}: OwnProps) { + const wrapperRef = useRef(null); + + const { closeBoardCardField } = useBoardCardField(); + + useListenClickOutsideArrayOfRef([wrapperRef], () => { + closeBoardCardField(); + }); + + useScopedHotkeys( + 'enter', + () => { + closeBoardCardField(); + }, + InternalHotkeysScope.BoardCardFieldEditMode, + [closeBoardCardField], + ); + + useScopedHotkeys( + 'esc', + () => { + closeBoardCardField(); + }, + InternalHotkeysScope.BoardCardFieldEditMode, + [closeBoardCardField], + ); + + return ( + + {children} + + ); +} diff --git a/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldInternal.tsx b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldInternal.tsx new file mode 100644 index 000000000..c55ae8792 --- /dev/null +++ b/front/src/modules/ui/board-card-field/components/BoardCardEditableFieldInternal.tsx @@ -0,0 +1,71 @@ +import { ReactElement } from 'react'; +import styled from '@emotion/styled'; + +import { useAddToHotkeysScopeStack } from '@/hotkeys/hooks/useAddToHotkeysScopeStack'; +import { HotkeysScopeStackItem } from '@/hotkeys/types/internal/HotkeysScopeStackItems'; +import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope'; + +import { useBoardCardField } from '../hooks/useBoardCardField'; + +import { BoardCardEditableFieldDisplayMode } from './BoardCardEditableFieldDisplayMode'; +import { BoardCardEditableFieldEditMode } from './BoardCardEditableFieldEditMode'; + +export const BoardCardFieldContainer = styled.div` + align-items: center; + box-sizing: border-box; + cursor: pointer; + display: flex; + height: 32px; + position: relative; + user-select: none; + width: 100%; +`; + +type OwnProps = { + editModeContent: ReactElement; + nonEditModeContent: ReactElement; + editModeHorizontalAlign?: 'left' | 'right'; + editModeVerticalPosition?: 'over' | 'below'; + editHotkeysScope?: HotkeysScopeStackItem; +}; + +export function BoardCardEditableFieldInternal({ + editModeHorizontalAlign = 'left', + editModeVerticalPosition = 'over', + editModeContent, + nonEditModeContent, + editHotkeysScope, +}: OwnProps) { + const { openBoardCardField, isBoardCardFieldInEditMode } = + useBoardCardField(); + + const addToHotkeysScopeStack = useAddToHotkeysScopeStack(); + + function handleOnClick() { + if (!isBoardCardFieldInEditMode) { + openBoardCardField(); + addToHotkeysScopeStack( + editHotkeysScope ?? { + scope: InternalHotkeysScope.BoardCardFieldEditMode, + }, + ); + } + } + + return ( + + {isBoardCardFieldInEditMode ? ( + + {editModeContent} + + ) : ( + + {nonEditModeContent} + + )} + + ); +} diff --git a/front/src/modules/ui/board-card-field/hooks/useBoardCardField.ts b/front/src/modules/ui/board-card-field/hooks/useBoardCardField.ts new file mode 100644 index 000000000..a7f46aa9c --- /dev/null +++ b/front/src/modules/ui/board-card-field/hooks/useBoardCardField.ts @@ -0,0 +1,26 @@ +import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState'; + +import { BoardCardFieldContext } from '../states/BoardCardFieldContext'; +import { isBoardCardFieldInEditModeScopedState } from '../states/isBoardCardFieldInEditModeScopedState'; + +export function useBoardCardField() { + const [isBoardCardFieldInEditMode, setIsBoardCardFieldInEditMode] = + useRecoilScopedState( + isBoardCardFieldInEditModeScopedState, + BoardCardFieldContext, + ); + + function openBoardCardField() { + setIsBoardCardFieldInEditMode(true); + } + + function closeBoardCardField() { + setIsBoardCardFieldInEditMode(false); + } + + return { + isBoardCardFieldInEditMode, + openBoardCardField, + closeBoardCardField, + }; +} diff --git a/front/src/modules/ui/board-card-field/states/BoardCardFieldContext.ts b/front/src/modules/ui/board-card-field/states/BoardCardFieldContext.ts new file mode 100644 index 000000000..6d8beeb4e --- /dev/null +++ b/front/src/modules/ui/board-card-field/states/BoardCardFieldContext.ts @@ -0,0 +1,3 @@ +import { createContext } from 'react'; + +export const BoardCardFieldContext = createContext(null); diff --git a/front/src/modules/ui/board-card-field/states/isBoardCardFieldInEditModeScopedState.ts b/front/src/modules/ui/board-card-field/states/isBoardCardFieldInEditModeScopedState.ts new file mode 100644 index 000000000..2fda71a0c --- /dev/null +++ b/front/src/modules/ui/board-card-field/states/isBoardCardFieldInEditModeScopedState.ts @@ -0,0 +1,9 @@ +import { atomFamily } from 'recoil'; + +export const isBoardCardFieldInEditModeScopedState = atomFamily< + boolean, + string +>({ + key: 'isBoardCardFieldInEditModeScopedState', + default: false, +}); diff --git a/front/src/modules/ui/components/board/Board.tsx b/front/src/modules/ui/board/components/Board.tsx similarity index 100% rename from front/src/modules/ui/components/board/Board.tsx rename to front/src/modules/ui/board/components/Board.tsx diff --git a/front/src/modules/ui/components/board/BoardColumn.tsx b/front/src/modules/ui/board/components/BoardColumn.tsx similarity index 100% rename from front/src/modules/ui/components/board/BoardColumn.tsx rename to front/src/modules/ui/board/components/BoardColumn.tsx diff --git a/front/src/modules/ui/components/board/NewButton.tsx b/front/src/modules/ui/board/components/NewButton.tsx similarity index 100% rename from front/src/modules/ui/components/board/NewButton.tsx rename to front/src/modules/ui/board/components/NewButton.tsx diff --git a/front/src/modules/ui/components/board/__tests__/Board.test.ts b/front/src/modules/ui/board/components/__tests__/Board.test.ts similarity index 74% rename from front/src/modules/ui/components/board/__tests__/Board.test.ts rename to front/src/modules/ui/board/components/__tests__/Board.test.ts index dc0171223..da712fcda 100644 --- a/front/src/modules/ui/components/board/__tests__/Board.test.ts +++ b/front/src/modules/ui/board/components/__tests__/Board.test.ts @@ -1,14 +1,14 @@ import { DropResult } from '@hello-pangea/dnd'; -import { BoardItemKey, getOptimisticlyUpdatedBoard } from '../Board'; +import { getOptimisticlyUpdatedBoard } from '../Board'; describe('getOptimisticlyUpdatedBoard', () => { it('should return a new board with the updated cell', () => { - const initialColumn1: BoardItemKey[] = ['item-1', 'item-2', 'item-3']; - const initialColumn2: BoardItemKey[] = ['item-4', 'item-5']; + const initialColumn1: string[] = ['item-1', 'item-2', 'item-3']; + const initialColumn2: string[] = ['item-4', 'item-5']; - const finalColumn1: BoardItemKey[] = ['item-2', 'item-3']; - const finalColumn2: BoardItemKey[] = ['item-4', 'item-1', 'item-5']; + const finalColumn1: string[] = ['item-2', 'item-3']; + const finalColumn2: string[] = ['item-4', 'item-1', 'item-5']; const dropResult = { source: { diff --git a/front/src/modules/ui/components/editable-cell/EditableCell.tsx b/front/src/modules/ui/components/editable-cell/EditableCell.tsx index 888e26ccd..5dbd10171 100644 --- a/front/src/modules/ui/components/editable-cell/EditableCell.tsx +++ b/front/src/modules/ui/components/editable-cell/EditableCell.tsx @@ -1,14 +1,13 @@ import { ReactElement } from 'react'; import styled from '@emotion/styled'; -import { useAddToHotkeysScopeStack } from '@/hotkeys/hooks/useAddToHotkeysScopeStack'; import { HotkeysScopeStackItem } from '@/hotkeys/types/internal/HotkeysScopeStackItems'; import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope'; import { useEditableCell } from './hooks/useCloseEditableCell'; import { useCurrentCellEditMode } from './hooks/useCurrentCellEditMode'; import { useIsSoftFocusOnCurrentCell } from './hooks/useIsSoftFocusOnCurrentCell'; -import { useSoftFocusOnCurrentCell } from './hooks/useSetSoftFocusOnCurrentCell'; +import { useSetSoftFocusOnCurrentCell } from './hooks/useSetSoftFocusOnCurrentCell'; import { EditableCellDisplayMode } from './EditableCellDisplayMode'; import { EditableCellEditMode } from './EditableCellEditMode'; import { EditableCellSoftFocusMode } from './EditableCellSoftFocusMode'; @@ -41,14 +40,12 @@ export function EditableCell({ }: OwnProps) { const { isCurrentCellInEditMode } = useCurrentCellEditMode(); - const setSoftFocusOnCurrentCell = useSoftFocusOnCurrentCell(); + const setSoftFocusOnCurrentCell = useSetSoftFocusOnCurrentCell(); const { openEditableCell } = useEditableCell(); const hasSoftFocus = useIsSoftFocusOnCurrentCell(); - const addToHotkeysScopeStack = useAddToHotkeysScopeStack(); - // TODO: we might have silent problematic behavior because of the setTimeout in openEditableCell, investigate // Maybe we could build a switchEditableCell to handle the case where we go from one cell to another. // See https://github.com/twentyhq/twenty/issues/446 @@ -58,8 +55,7 @@ export function EditableCell({ } if (hasSoftFocus) { - openEditableCell(); - addToHotkeysScopeStack( + openEditableCell( editHotkeysScope ?? { scope: InternalHotkeysScope.CellEditMode, }, diff --git a/front/src/modules/ui/components/editable-cell/EditableCellSoftFocusMode.tsx b/front/src/modules/ui/components/editable-cell/EditableCellSoftFocusMode.tsx index f098534d1..653dba3de 100644 --- a/front/src/modules/ui/components/editable-cell/EditableCellSoftFocusMode.tsx +++ b/front/src/modules/ui/components/editable-cell/EditableCellSoftFocusMode.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { useAddToHotkeysScopeStack } from '@/hotkeys/hooks/useAddToHotkeysScopeStack'; import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys'; import { HotkeysScopeStackItem } from '@/hotkeys/types/internal/HotkeysScopeStackItems'; import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope'; @@ -14,20 +13,18 @@ export function EditableCellSoftFocusMode({ editHotkeysScope, }: React.PropsWithChildren<{ editHotkeysScope?: HotkeysScopeStackItem }>) { const { closeEditableCell, openEditableCell } = useEditableCell(); - const addToHotkeysScopeStack = useAddToHotkeysScopeStack(); useScopedHotkeys( 'enter', () => { - openEditableCell(); - addToHotkeysScopeStack( + openEditableCell( editHotkeysScope ?? { scope: InternalHotkeysScope.CellEditMode, }, ); }, InternalHotkeysScope.TableSoftFocus, - [closeEditableCell], + [closeEditableCell, editHotkeysScope], ); useScopedHotkeys( @@ -42,15 +39,14 @@ export function EditableCellSoftFocusMode({ return; } - openEditableCell(); - addToHotkeysScopeStack( + openEditableCell( editHotkeysScope ?? { scope: InternalHotkeysScope.CellEditMode, }, ); }, InternalHotkeysScope.TableSoftFocus, - [openEditableCell, addToHotkeysScopeStack, editHotkeysScope], + [openEditableCell, editHotkeysScope], { preventDefault: false, }, diff --git a/front/src/modules/ui/components/editable-cell/hooks/useCloseEditableCell.ts b/front/src/modules/ui/components/editable-cell/hooks/useCloseEditableCell.ts index 2cec0221b..6f43d56d9 100644 --- a/front/src/modules/ui/components/editable-cell/hooks/useCloseEditableCell.ts +++ b/front/src/modules/ui/components/editable-cell/hooks/useCloseEditableCell.ts @@ -1,6 +1,8 @@ import { useRecoilCallback } from 'recoil'; +import { useAddToHotkeysScopeStack } from '@/hotkeys/hooks/useAddToHotkeysScopeStack'; import { useRemoveHighestHotkeysScopeStackItem } from '@/hotkeys/hooks/useRemoveHighestHotkeysScopeStackItem'; +import { HotkeysScopeStackItem } from '@/hotkeys/types/internal/HotkeysScopeStackItems'; import { useCloseCurrentCellInEditMode } from '@/ui/tables/hooks/useClearCellInEditMode'; import { isSoftFocusActiveState } from '@/ui/tables/states/isSoftFocusActiveState'; import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState'; @@ -10,6 +12,8 @@ import { useCurrentCellEditMode } from './useCurrentCellEditMode'; export function useEditableCell() { const { setCurrentCellInEditMode } = useCurrentCellEditMode(); + const addToHotkeysScopeStack = useAddToHotkeysScopeStack(); + const closeCurrentCellInEditMode = useCloseCurrentCellInEditMode(); const removeHighestHotkeysScopedStackItem = @@ -22,7 +26,7 @@ export function useEditableCell() { const openEditableCell = useRecoilCallback( ({ snapshot, set }) => - () => { + (hotkeysScopeStackItem: HotkeysScopeStackItem) => { const isSomeInputInEditMode = snapshot .getLoadable(isSomeInputInEditModeState) .valueOrThrow(); @@ -32,9 +36,11 @@ export function useEditableCell() { set(isSoftFocusActiveState, false); setCurrentCellInEditMode(); + + addToHotkeysScopeStack(hotkeysScopeStackItem); } }, - [setCurrentCellInEditMode], + [setCurrentCellInEditMode, addToHotkeysScopeStack], ); return { diff --git a/front/src/modules/ui/components/editable-cell/hooks/useSetSoftFocusOnCurrentCell.ts b/front/src/modules/ui/components/editable-cell/hooks/useSetSoftFocusOnCurrentCell.ts index cea6636a0..cbd6b7b25 100644 --- a/front/src/modules/ui/components/editable-cell/hooks/useSetSoftFocusOnCurrentCell.ts +++ b/front/src/modules/ui/components/editable-cell/hooks/useSetSoftFocusOnCurrentCell.ts @@ -12,7 +12,7 @@ import { isSoftFocusActiveState } from '@/ui/tables/states/isSoftFocusActiveStat import { RowContext } from '@/ui/tables/states/RowContext'; import { CellPosition } from '@/ui/tables/types/CellPosition'; -export function useSoftFocusOnCurrentCell() { +export function useSetSoftFocusOnCurrentCell() { const setSoftFocusPosition = useSetSoftFocusPosition(); const [currentRowNumber] = useRecoilScopedState( currentRowNumberScopedState, diff --git a/front/src/modules/ui/components/editable-cell/types/EditableCellDate.tsx b/front/src/modules/ui/components/editable-cell/types/EditableCellDate.tsx new file mode 100644 index 000000000..f62041cbc --- /dev/null +++ b/front/src/modules/ui/components/editable-cell/types/EditableCellDate.tsx @@ -0,0 +1,29 @@ +import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope'; +import { InplaceInputDateDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputDateDisplayMode'; + +import { EditableCell } from '../EditableCell'; + +import { EditableCellDateEditMode } from './EditableCellDateEditMode'; + +export type EditableDateProps = { + value: Date; + onChange: (date: Date) => void; + editModeHorizontalAlign?: 'left' | 'right'; +}; + +export function EditableCellDate({ + value, + onChange, + editModeHorizontalAlign, +}: EditableDateProps) { + return ( + + } + nonEditModeContent={} + editHotkeysScope={{ scope: InternalHotkeysScope.CellDateEditMode }} + > + ); +} diff --git a/front/src/modules/ui/components/editable-cell/types/EditableCellDateEditMode.tsx b/front/src/modules/ui/components/editable-cell/types/EditableCellDateEditMode.tsx new file mode 100644 index 000000000..f072c6a60 --- /dev/null +++ b/front/src/modules/ui/components/editable-cell/types/EditableCellDateEditMode.tsx @@ -0,0 +1,22 @@ +import { InplaceInputDateEditMode } from '@/ui/inplace-inputs/components/InplaceInputDateEditMode'; + +import { useEditableCell } from '../hooks/useCloseEditableCell'; + +export type EditableDateProps = { + value: Date; + onChange: (date: Date) => void; +}; + +export function EditableCellDateEditMode({ + value, + onChange, +}: EditableDateProps) { + const { closeEditableCell } = useEditableCell(); + + function handleDateChange(newDate: Date) { + onChange(newDate); + closeEditableCell(); + } + + return ; +} diff --git a/front/src/modules/ui/components/editable-cell/types/EditableDoubleText.tsx b/front/src/modules/ui/components/editable-cell/types/EditableCellDoubleText.tsx similarity index 85% rename from front/src/modules/ui/components/editable-cell/types/EditableDoubleText.tsx rename to front/src/modules/ui/components/editable-cell/types/EditableCellDoubleText.tsx index ecdcfb6cd..2a22db373 100644 --- a/front/src/modules/ui/components/editable-cell/types/EditableDoubleText.tsx +++ b/front/src/modules/ui/components/editable-cell/types/EditableCellDoubleText.tsx @@ -4,7 +4,7 @@ import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysSc import { EditableCell } from '../EditableCell'; -import { EditableDoubleTextEditMode } from './EditableDoubleTextEditMode'; +import { EditableCellDoubleTextEditMode } from './EditableCellDoubleTextEditMode'; type OwnProps = { firstValue: string; @@ -15,7 +15,7 @@ type OwnProps = { onChange: (firstValue: string, secondValue: string) => void; }; -export function EditableDoubleText({ +export function EditableCellDoubleText({ firstValue, secondValue, firstValuePlaceholder, @@ -27,7 +27,7 @@ export function EditableDoubleText({ { + () => { if (focusPosition === 'left') { setFocusPosition('right'); secondValueInputRef.current?.focus(); @@ -107,7 +99,7 @@ export function EditableDoubleTextEditMode({ return ( - - void; +}; + +export function EditableCellPhone({ + value, + placeholder, + changeHandler, +}: OwnProps) { + const inputRef = useRef(null); + const [inputValue, setInputValue] = useState(value); + + return ( + ) => { + setInputValue(event.target.value); + changeHandler(event.target.value); + }} + /> + } + nonEditModeContent={} + /> + ); +} diff --git a/front/src/modules/ui/components/editable-cell/types/EditableRelationCreateButton.tsx b/front/src/modules/ui/components/editable-cell/types/EditableCellRelationCreateButton.tsx similarity index 88% rename from front/src/modules/ui/components/editable-cell/types/EditableRelationCreateButton.tsx rename to front/src/modules/ui/components/editable-cell/types/EditableCellRelationCreateButton.tsx index f1ce9a4bd..ca1a67bb4 100644 --- a/front/src/modules/ui/components/editable-cell/types/EditableRelationCreateButton.tsx +++ b/front/src/modules/ui/components/editable-cell/types/EditableCellRelationCreateButton.tsx @@ -1,6 +1,6 @@ import styled from '@emotion/styled'; -export const EditableRelationCreateButton = styled.button` +export const EditableCellRelationCreateButton = styled.button` align-items: center; background: none; border: none; diff --git a/front/src/modules/ui/components/editable-cell/types/EditableCellText.tsx b/front/src/modules/ui/components/editable-cell/types/EditableCellText.tsx new file mode 100644 index 000000000..9b54641f0 --- /dev/null +++ b/front/src/modules/ui/components/editable-cell/types/EditableCellText.tsx @@ -0,0 +1,39 @@ +import { ChangeEvent } from 'react'; + +import { InplaceInputTextDisplayMode } from '@/ui/inplace-inputs/components/InplaceInputTextDisplayMode'; +import { InplaceInputTextEditMode } from '@/ui/inplace-inputs/components/InplaceInputTextEditMode'; + +import { EditableCell } from '../EditableCell'; + +type OwnProps = { + placeholder?: string; + value: string; + onChange: (newValue: string) => void; + editModeHorizontalAlign?: 'left' | 'right'; +}; + +export function EditableCellText({ + value, + placeholder, + onChange, + editModeHorizontalAlign, +}: OwnProps) { + return ( + ) => { + onChange(event.target.value); + }} + /> + } + nonEditModeContent={ + {value} + } + > + ); +} diff --git a/front/src/modules/ui/components/editable-cell/types/EditableChip.tsx b/front/src/modules/ui/components/editable-cell/types/EditableChip.tsx index 3c228b280..089b66650 100644 --- a/front/src/modules/ui/components/editable-cell/types/EditableChip.tsx +++ b/front/src/modules/ui/components/editable-cell/types/EditableChip.tsx @@ -39,7 +39,8 @@ const RightContainer = styled.div` margin-left: ${(props) => props.theme.spacing(1)}; `; -function EditableChip({ +// TODO: move right end content in EditableCell +export function EditableCellChip({ value, placeholder, changeHandler, @@ -89,5 +90,3 @@ function EditableChip({ /> ); } - -export default EditableChip; diff --git a/front/src/modules/ui/components/editable-cell/types/EditableDate.tsx b/front/src/modules/ui/components/editable-cell/types/EditableDate.tsx deleted file mode 100644 index 9c8e46fa0..000000000 --- a/front/src/modules/ui/components/editable-cell/types/EditableDate.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { forwardRef, useState } from 'react'; -import styled from '@emotion/styled'; - -import { humanReadableDate } from '@/utils/utils'; - -import DatePicker from '../../form/DatePicker'; -import { EditableCell } from '../EditableCell'; - -export type EditableDateProps = { - value: Date; - changeHandler: (date: Date) => void; - editModeHorizontalAlign?: 'left' | 'right'; -}; - -const StyledContainer = styled.div` - align-items: center; - display: flex; - margin: 0px ${({ theme }) => theme.spacing(2)}; -`; - -export type StyledCalendarContainerProps = { - editModeHorizontalAlign?: 'left' | 'right'; -}; - -const StyledCalendarContainer = styled.div` - background: ${({ theme }) => theme.background.secondary}; - border: 1px solid ${({ theme }) => theme.border.color.light}; - border-radius: 8px; - box-shadow: ${({ theme }) => theme.boxShadow.strong}; - left: -10px; - position: absolute; - top: 10px; - z-index: 1; -`; -export function EditableDate({ - value, - changeHandler, - editModeHorizontalAlign, -}: EditableDateProps) { - const [inputValue, setInputValue] = useState(value); - - type DivProps = React.HTMLProps; - - const DateDisplay = forwardRef( - ({ value, onClick }, ref) => ( -
- {value && humanReadableDate(new Date(value as string))} -
- ), - ); - - type DatePickerContainerProps = { - children: React.ReactNode; - }; - - const DatePickerContainer = ({ children }: DatePickerContainerProps) => { - return {children}; - }; - - return ( - - { - changeHandler(date); - setInputValue(date); - }} - customInput={} - customCalendarContainer={DatePickerContainer} - /> -
- } - nonEditModeContent={ -
{inputValue && humanReadableDate(inputValue)}
- } - >
- ); -} diff --git a/front/src/modules/ui/components/editable-cell/types/EditablePhone.tsx b/front/src/modules/ui/components/editable-cell/types/EditablePhone.tsx deleted file mode 100644 index cdb341c35..000000000 --- a/front/src/modules/ui/components/editable-cell/types/EditablePhone.tsx +++ /dev/null @@ -1,70 +0,0 @@ -import { ChangeEvent, MouseEvent, useRef, useState } from 'react'; -import styled from '@emotion/styled'; -import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js'; - -import { textInputStyle } from '@/ui/themes/effects'; - -import { RawLink } from '../../links/RawLink'; -import { EditableCell } from '../EditableCell'; - -type OwnProps = { - placeholder?: string; - value: string; - changeHandler: (updated: string) => void; -}; - -const StyledRawLink = styled(RawLink)` - overflow: hidden; - - a { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -`; - -// TODO: refactor -const StyledEditInplaceInput = styled.input` - margin: 0; - width: 100%; - ${textInputStyle} -`; - -export function EditablePhone({ value, placeholder, changeHandler }: OwnProps) { - const inputRef = useRef(null); - const [inputValue, setInputValue] = useState(value); - - return ( - ) => { - setInputValue(event.target.value); - changeHandler(event.target.value); - }} - /> - } - nonEditModeContent={ - <> - {isValidPhoneNumber(inputValue) ? ( - ) => { - event.stopPropagation(); - }} - > - {parsePhoneNumber(inputValue, 'FR')?.formatInternational() || - inputValue} - - ) : ( - {inputValue} - )} - - } - /> - ); -} diff --git a/front/src/modules/ui/components/editable-cell/types/EditableText.tsx b/front/src/modules/ui/components/editable-cell/types/EditableText.tsx deleted file mode 100644 index aeea86426..000000000 --- a/front/src/modules/ui/components/editable-cell/types/EditableText.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import { ChangeEvent, useRef, useState } from 'react'; -import styled from '@emotion/styled'; - -import { textInputStyle } from '@/ui/themes/effects'; - -import { EditableCell } from '../EditableCell'; - -type OwnProps = { - placeholder?: string; - content: string; - changeHandler: (updated: string) => void; - editModeHorizontalAlign?: 'left' | 'right'; -}; - -// TODO: refactor -const StyledInplaceInput = styled.input` - margin: 0; - width: 100%; - ${textInputStyle} -`; - -const StyledNoEditText = styled.div` - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - width: 100%; -`; - -export function EditableText({ - content, - placeholder, - changeHandler, - editModeHorizontalAlign, -}: OwnProps) { - const inputRef = useRef(null); - const [inputValue, setInputValue] = useState(content); - - return ( - ) => { - setInputValue(event.target.value); - changeHandler(event.target.value); - }} - /> - } - nonEditModeContent={{inputValue}} - > - ); -} diff --git a/front/src/modules/ui/inplace-inputs/components/InplaceInputDateDisplayMode.tsx b/front/src/modules/ui/inplace-inputs/components/InplaceInputDateDisplayMode.tsx new file mode 100644 index 000000000..5a9f826fa --- /dev/null +++ b/front/src/modules/ui/inplace-inputs/components/InplaceInputDateDisplayMode.tsx @@ -0,0 +1,9 @@ +import { humanReadableDate } from '@/utils/utils'; + +type OwnProps = { + value: Date; +}; + +export function InplaceInputDateDisplayMode({ value }: OwnProps) { + return
{value && humanReadableDate(value)}
; +} diff --git a/front/src/modules/ui/inplace-inputs/components/InplaceInputDateEditMode.tsx b/front/src/modules/ui/inplace-inputs/components/InplaceInputDateEditMode.tsx new file mode 100644 index 000000000..c1e212e35 --- /dev/null +++ b/front/src/modules/ui/inplace-inputs/components/InplaceInputDateEditMode.tsx @@ -0,0 +1,62 @@ +import { forwardRef } from 'react'; +import styled from '@emotion/styled'; + +import DatePicker from '@/ui/components/form/DatePicker'; +import { humanReadableDate } from '@/utils/utils'; + +const StyledContainer = styled.div` + align-items: center; + display: flex; + margin: 0px ${({ theme }) => theme.spacing(2)}; +`; + +export type StyledCalendarContainerProps = { + editModeHorizontalAlign?: 'left' | 'right'; +}; + +const StyledCalendarContainer = styled.div` + background: ${({ theme }) => theme.background.secondary}; + border: 1px solid ${({ theme }) => theme.border.color.light}; + border-radius: 8px; + box-shadow: ${({ theme }) => theme.boxShadow.strong}; + left: -10px; + position: absolute; + top: 10px; + z-index: 1; +`; + +type DivProps = React.HTMLProps; + +const DateDisplay = forwardRef( + ({ value, onClick }, ref) => ( +
+ {value && humanReadableDate(new Date(value as string))} +
+ ), +); + +type DatePickerContainerProps = { + children: React.ReactNode; +}; + +const DatePickerContainer = ({ children }: DatePickerContainerProps) => { + return {children}; +}; + +type OwnProps = { + value: Date; + onChange: (newDate: Date) => void; +}; + +export function InplaceInputDateEditMode({ onChange, value }: OwnProps) { + return ( + + } + customCalendarContainer={DatePickerContainer} + /> + + ); +} diff --git a/front/src/modules/ui/inplace-inputs/components/InplaceInputPhoneDisplayMode.tsx b/front/src/modules/ui/inplace-inputs/components/InplaceInputPhoneDisplayMode.tsx new file mode 100644 index 000000000..36bc7c5db --- /dev/null +++ b/front/src/modules/ui/inplace-inputs/components/InplaceInputPhoneDisplayMode.tsx @@ -0,0 +1,34 @@ +import { MouseEvent } from 'react'; +import styled from '@emotion/styled'; +import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js'; + +import { RawLink } from '@/ui/components/links/RawLink'; + +const StyledRawLink = styled(RawLink)` + overflow: hidden; + + a { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +`; + +type OwnProps = { + value: string; +}; + +export function InplaceInputPhoneDisplayMode({ value }: OwnProps) { + return isValidPhoneNumber(value) ? ( + ) => { + event.stopPropagation(); + }} + > + {parsePhoneNumber(value, 'FR')?.formatInternational() || value} + + ) : ( + {value} + ); +} diff --git a/front/src/modules/ui/inplace-inputs/components/InplaceInputTextDisplayMode.tsx b/front/src/modules/ui/inplace-inputs/components/InplaceInputTextDisplayMode.tsx new file mode 100644 index 000000000..0bf93f8d6 --- /dev/null +++ b/front/src/modules/ui/inplace-inputs/components/InplaceInputTextDisplayMode.tsx @@ -0,0 +1,8 @@ +import styled from '@emotion/styled'; + +export const InplaceInputTextDisplayMode = styled.div` + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + width: 100%; +`; diff --git a/front/src/modules/ui/inplace-inputs/components/InplaceInputTextEditMode.tsx b/front/src/modules/ui/inplace-inputs/components/InplaceInputTextEditMode.tsx new file mode 100644 index 000000000..d33a0240c --- /dev/null +++ b/front/src/modules/ui/inplace-inputs/components/InplaceInputTextEditMode.tsx @@ -0,0 +1,9 @@ +import styled from '@emotion/styled'; + +import { textInputStyle } from '@/ui/themes/effects'; + +export const InplaceInputTextEditMode = styled.input` + margin: 0; + width: 100%; + ${textInputStyle} +`; diff --git a/front/src/modules/ui/tables/hooks/useClearCellInEditMode.ts b/front/src/modules/ui/tables/hooks/useClearCellInEditMode.ts index 275d37dfe..129b885d8 100644 --- a/front/src/modules/ui/tables/hooks/useClearCellInEditMode.ts +++ b/front/src/modules/ui/tables/hooks/useClearCellInEditMode.ts @@ -13,6 +13,7 @@ export function useCloseCurrentCellInEditMode() { set(isCellInEditModeFamilyState(currentCellInEditModePosition), false); + // TODO: find a way to remove this await new Promise((resolve) => setTimeout(resolve, 20)); set(isSomeInputInEditModeState, false); diff --git a/front/src/pages/companies/companies-columns.tsx b/front/src/pages/companies/companies-columns.tsx index 1374e8e03..18974f698 100644 --- a/front/src/pages/companies/companies-columns.tsx +++ b/front/src/pages/companies/companies-columns.tsx @@ -3,8 +3,8 @@ import { createColumnHelper } from '@tanstack/react-table'; import { CompanyAccountOwnerCell } from '@/companies/components/CompanyAccountOwnerCell'; import { CompanyEditableNameChipCell } from '@/companies/components/CompanyEditableNameCell'; -import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate'; -import { EditableText } from '@/ui/components/editable-cell/types/EditableText'; +import { EditableCellDate } from '@/ui/components/editable-cell/types/EditableCellDate'; +import { EditableCellText } from '@/ui/components/editable-cell/types/EditableCellText'; import { ColumnHead } from '@/ui/components/table/ColumnHead'; import { IconBuildingSkyscraper, @@ -44,10 +44,10 @@ export const useCompaniesColumns = () => { } /> ), cell: (props) => ( - { + onChange={(value) => { const company = { ...props.row.original }; company.domainName = value; updateCompany({ @@ -66,10 +66,10 @@ export const useCompaniesColumns = () => { } /> ), cell: (props) => ( - { + onChange={(value) => { const company = { ...props.row.original }; updateCompany({ @@ -89,10 +89,10 @@ export const useCompaniesColumns = () => { } /> ), cell: (props) => ( - { + onChange={(value) => { const company = { ...props.row.original }; company.address = value; updateCompany({ @@ -114,13 +114,13 @@ export const useCompaniesColumns = () => { /> ), cell: (props) => ( - { + onChange={(value: Date) => { const company = { ...props.row.original }; company.createdAt = value.toISOString(); updateCompany({ diff --git a/front/src/pages/opportunities/Opportunities.tsx b/front/src/pages/opportunities/Opportunities.tsx index 94eaa8905..d3c0b6f1c 100644 --- a/front/src/pages/opportunities/Opportunities.tsx +++ b/front/src/pages/opportunities/Opportunities.tsx @@ -1,8 +1,10 @@ import { useCallback, useMemo } from 'react'; +import { getOperationName } from '@apollo/client/utilities'; import { useTheme } from '@emotion/react'; import { BoardActionBarButtonDeletePipelineProgress } from '@/pipeline-progress/components/BoardActionBarButtonDeletePipelineProgress'; import { EntityBoardActionBar } from '@/pipeline-progress/components/EntityBoardActionBar'; +import { GET_PIPELINES } from '@/pipeline-progress/queries'; import { IconTargetArrow } from '@/ui/icons/index'; import { WithTopBarContainer } from '@/ui/layout/containers/WithTopBarContainer'; @@ -23,6 +25,7 @@ export function Opportunities() { const pipelineId = pipelines.data?.findManyPipeline[0].id; const { initialBoard, items } = useBoard(pipelineId || ''); + const columns = useMemo( () => initialBoard?.map(({ id, colorCode, title }) => ({ @@ -40,12 +43,13 @@ export function Opportunities() { async ( pipelineProgress: Pick, ) => { - updatePipelineProgress({ + await updatePipelineProgress({ variables: { id: pipelineProgress.id, amount: pipelineProgress.amount, closeDate: pipelineProgress.closeDate || null, }, + refetchQueries: [getOperationName(GET_PIPELINES) ?? ''], }); }, [updatePipelineProgress], diff --git a/front/src/pages/people/people-columns.tsx b/front/src/pages/people/people-columns.tsx index 3c9ee46c6..769ebec40 100644 --- a/front/src/pages/people/people-columns.tsx +++ b/front/src/pages/people/people-columns.tsx @@ -3,9 +3,9 @@ import { createColumnHelper } from '@tanstack/react-table'; import { EditablePeopleFullName } from '@/people/components/EditablePeopleFullName'; import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell'; -import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate'; -import { EditablePhone } from '@/ui/components/editable-cell/types/EditablePhone'; -import { EditableText } from '@/ui/components/editable-cell/types/EditableText'; +import { EditableCellDate } from '@/ui/components/editable-cell/types/EditableCellDate'; +import { EditableCellPhone } from '@/ui/components/editable-cell/types/EditableCellPhone'; +import { EditableCellText } from '@/ui/components/editable-cell/types/EditableCellText'; import { ColumnHead } from '@/ui/components/table/ColumnHead'; import { IconBuildingSkyscraper, @@ -55,10 +55,10 @@ export const usePeopleColumns = () => { } /> ), cell: (props) => ( - { + value={props.row.original.email || ''} + onChange={async (value: string) => { const person = props.row.original; await updatePerson({ variables: { @@ -87,7 +87,7 @@ export const usePeopleColumns = () => { } /> ), cell: (props) => ( - { @@ -112,13 +112,13 @@ export const usePeopleColumns = () => { /> ), cell: (props) => ( - { + onChange={async (value: Date) => { const person = { ...props.row.original }; await updatePerson({ variables: { @@ -137,11 +137,11 @@ export const usePeopleColumns = () => { } /> ), cell: (props) => ( - { + value={props.row.original.city || ''} + onChange={async (value: string) => { const person = { ...props.row.original }; await updatePerson({ variables: {