Persist table cell values on cell close (#655)
* Persist table cell values on cell close * Apply to all cells
This commit is contained in:
@ -26,6 +26,8 @@ type OwnProps = {
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
editModeVerticalPosition?: 'over' | 'below';
|
||||
editHotkeysScope?: HotkeysScope;
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
export function EditableCell({
|
||||
@ -34,6 +36,8 @@ export function EditableCell({
|
||||
editModeContent,
|
||||
nonEditModeContent,
|
||||
editHotkeysScope,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: OwnProps) {
|
||||
const { isCurrentCellInEditMode } = useCurrentCellEditMode();
|
||||
|
||||
@ -45,6 +49,8 @@ export function EditableCell({
|
||||
<EditableCellEditMode
|
||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||
editModeVerticalPosition={editModeVerticalPosition}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
{editModeContent}
|
||||
</EditableCellEditMode>
|
||||
|
||||
@ -1,13 +1,9 @@
|
||||
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 { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
||||
import { overlayBackground } from '@/ui/themes/effects';
|
||||
|
||||
import { useEditableCell } from './hooks/useEditableCell';
|
||||
import { useRegisterCloseCellHandlers } from './hooks/useRegisterCloseCellHandlers';
|
||||
|
||||
export const EditableCellEditModeContainer = styled.div<OwnProps>`
|
||||
align-items: center;
|
||||
@ -33,60 +29,20 @@ type OwnProps = {
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
editModeVerticalPosition?: 'over' | 'below';
|
||||
onOutsideClick?: () => void;
|
||||
onCancel?: () => void;
|
||||
onSubmit?: () => void;
|
||||
};
|
||||
|
||||
export function EditableCellEditMode({
|
||||
editModeHorizontalAlign,
|
||||
editModeVerticalPosition,
|
||||
children,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
}: OwnProps) {
|
||||
const wrapperRef = useRef(null);
|
||||
|
||||
const { closeEditableCell } = useEditableCell();
|
||||
const { moveRight, moveLeft, moveDown } = useMoveSoftFocus();
|
||||
|
||||
useListenClickOutsideArrayOfRef([wrapperRef], () => {
|
||||
closeEditableCell();
|
||||
});
|
||||
|
||||
useScopedHotkeys(
|
||||
'enter',
|
||||
() => {
|
||||
closeEditableCell();
|
||||
moveDown();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'esc',
|
||||
() => {
|
||||
closeEditableCell();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'tab',
|
||||
() => {
|
||||
closeEditableCell();
|
||||
moveRight();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, moveRight],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'shift+tab',
|
||||
() => {
|
||||
closeEditableCell();
|
||||
moveLeft();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, moveRight],
|
||||
);
|
||||
useRegisterCloseCellHandlers(wrapperRef, onSubmit, onCancel);
|
||||
|
||||
return (
|
||||
<EditableCellEditModeContainer
|
||||
|
||||
@ -4,7 +4,6 @@ import { useSetHotkeysScope } from '@/hotkeys/hooks/useSetHotkeysScope';
|
||||
import { HotkeysScope } from '@/hotkeys/types/internal/HotkeysScope';
|
||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
||||
import { useCloseCurrentCellInEditMode } from '@/ui/tables/hooks/useClearCellInEditMode';
|
||||
import { isSoftFocusActiveState } from '@/ui/tables/states/isSoftFocusActiveState';
|
||||
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
||||
|
||||
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
||||
@ -30,7 +29,6 @@ export function useEditableCell() {
|
||||
|
||||
if (!isSomeInputInEditMode) {
|
||||
set(isSomeInputInEditModeState, true);
|
||||
set(isSoftFocusActiveState, false);
|
||||
|
||||
setCurrentCellInEditMode();
|
||||
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||
import { useMoveSoftFocus } from '@/ui/tables/hooks/useMoveSoftFocus';
|
||||
|
||||
import { useCurrentCellEditMode } from './useCurrentCellEditMode';
|
||||
import { useEditableCell } from './useEditableCell';
|
||||
|
||||
export function useRegisterCloseCellHandlers(
|
||||
wrapperRef: React.RefObject<HTMLDivElement>,
|
||||
onSubmit?: () => void,
|
||||
onCancel?: () => void,
|
||||
) {
|
||||
const { closeEditableCell } = useEditableCell();
|
||||
const { isCurrentCellInEditMode } = useCurrentCellEditMode();
|
||||
useListenClickOutsideArrayOfRef([wrapperRef], () => {
|
||||
if (isCurrentCellInEditMode) {
|
||||
onSubmit?.();
|
||||
closeEditableCell();
|
||||
}
|
||||
});
|
||||
const { moveRight, moveLeft, moveDown } = useMoveSoftFocus();
|
||||
|
||||
useScopedHotkeys(
|
||||
'enter',
|
||||
() => {
|
||||
onSubmit?.();
|
||||
closeEditableCell();
|
||||
moveDown();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, onSubmit, moveDown],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'esc',
|
||||
() => {
|
||||
closeEditableCell();
|
||||
onCancel?.();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, onCancel],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'tab',
|
||||
() => {
|
||||
onSubmit?.();
|
||||
closeEditableCell();
|
||||
moveRight();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, onSubmit, moveRight],
|
||||
);
|
||||
|
||||
useScopedHotkeys(
|
||||
'shift+tab',
|
||||
() => {
|
||||
onSubmit?.();
|
||||
closeEditableCell();
|
||||
moveLeft();
|
||||
},
|
||||
InternalHotkeysScope.CellEditMode,
|
||||
[closeEditableCell, onSubmit, moveRight],
|
||||
);
|
||||
}
|
||||
@ -14,6 +14,8 @@ type OwnProps = {
|
||||
secondValuePlaceholder: string;
|
||||
nonEditModeContent: ReactElement;
|
||||
onChange: (firstValue: string, secondValue: string) => void;
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
loading?: boolean;
|
||||
};
|
||||
|
||||
@ -23,6 +25,8 @@ export function EditableCellDoubleText({
|
||||
firstValuePlaceholder,
|
||||
secondValuePlaceholder,
|
||||
onChange,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
nonEditModeContent,
|
||||
loading,
|
||||
}: OwnProps) {
|
||||
@ -50,6 +54,8 @@ export function EditableCellDoubleText({
|
||||
firstValuePlaceholder={firstValuePlaceholder}
|
||||
secondValuePlaceholder={secondValuePlaceholder}
|
||||
onChange={handleOnChange}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={onCancel}
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={loading ? <CellSkeleton /> : nonEditModeContent}
|
||||
|
||||
@ -15,8 +15,8 @@ type OwnProps = {
|
||||
firstValuePlaceholder: string;
|
||||
secondValuePlaceholder: string;
|
||||
onChange: (firstValue: string, secondValue: string) => void;
|
||||
onSubmit?: (firstValue: string, secondValue: string) => void;
|
||||
onExit?: () => void;
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@ -37,7 +37,7 @@ export function EditableCellDoubleTextEditMode({
|
||||
secondValuePlaceholder,
|
||||
onChange,
|
||||
onSubmit,
|
||||
onExit,
|
||||
onCancel,
|
||||
}: OwnProps) {
|
||||
const [focusPosition, setFocusPosition] = useState<'left' | 'right'>('left');
|
||||
|
||||
@ -57,9 +57,7 @@ export function EditableCellDoubleTextEditMode({
|
||||
() => {
|
||||
closeCell();
|
||||
moveDown();
|
||||
if (onSubmit) {
|
||||
onSubmit(firstValue, secondValue);
|
||||
}
|
||||
onSubmit?.();
|
||||
},
|
||||
InternalHotkeysScope.CellDoubleTextInput,
|
||||
[closeCell],
|
||||
@ -68,9 +66,7 @@ export function EditableCellDoubleTextEditMode({
|
||||
useScopedHotkeys(
|
||||
Key.Escape,
|
||||
() => {
|
||||
if (onExit) {
|
||||
onExit();
|
||||
}
|
||||
onCancel?.();
|
||||
closeCell();
|
||||
},
|
||||
InternalHotkeysScope.CellDoubleTextInput,
|
||||
@ -84,9 +80,7 @@ export function EditableCellDoubleTextEditMode({
|
||||
setFocusPosition('right');
|
||||
secondValueInputRef.current?.focus();
|
||||
} else {
|
||||
if (onExit) {
|
||||
onExit();
|
||||
}
|
||||
onSubmit?.();
|
||||
closeCell();
|
||||
moveRight();
|
||||
}
|
||||
@ -102,6 +96,7 @@ export function EditableCellDoubleTextEditMode({
|
||||
setFocusPosition('left');
|
||||
firstValueInputRef.current?.focus();
|
||||
} else {
|
||||
onSubmit?.();
|
||||
closeCell();
|
||||
moveLeft();
|
||||
}
|
||||
|
||||
@ -9,9 +9,17 @@ type OwnProps = {
|
||||
placeholder?: string;
|
||||
value: string;
|
||||
onChange: (updated: string) => void;
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
export function EditableCellPhone({ value, placeholder, onChange }: OwnProps) {
|
||||
export function EditableCellPhone({
|
||||
value,
|
||||
placeholder,
|
||||
onChange,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: OwnProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
|
||||
@ -34,6 +42,8 @@ export function EditableCellPhone({ value, placeholder, onChange }: OwnProps) {
|
||||
/>
|
||||
}
|
||||
nonEditModeContent={<InplaceInputPhoneDisplayMode value={inputValue} />}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={onCancel}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -12,6 +12,8 @@ type OwnProps = {
|
||||
onChange: (newValue: string) => void;
|
||||
editModeHorizontalAlign?: 'left' | 'right';
|
||||
loading?: boolean;
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
export function EditableCellText({
|
||||
@ -20,6 +22,8 @@ export function EditableCellText({
|
||||
onChange,
|
||||
editModeHorizontalAlign,
|
||||
loading,
|
||||
onCancel,
|
||||
onSubmit,
|
||||
}: OwnProps) {
|
||||
const [internalValue, setInternalValue] = useState(value);
|
||||
|
||||
@ -41,6 +45,8 @@ export function EditableCellText({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={onCancel}
|
||||
nonEditModeContent={
|
||||
loading ? (
|
||||
<CellSkeleton />
|
||||
|
||||
@ -28,6 +28,8 @@ export type EditableChipProps = {
|
||||
commentThreadCount?: number;
|
||||
onCommentClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
|
||||
rightEndContents?: ReactNode[];
|
||||
onSubmit?: () => void;
|
||||
onCancel?: () => void;
|
||||
};
|
||||
|
||||
// TODO: refactor
|
||||
@ -58,6 +60,8 @@ export function EditableCellChip({
|
||||
editModeHorizontalAlign,
|
||||
ChipComponent,
|
||||
rightEndContents,
|
||||
onSubmit,
|
||||
onCancel,
|
||||
}: EditableChipProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [inputValue, setInputValue] = useState(value);
|
||||
@ -87,6 +91,8 @@ export function EditableCellChip({
|
||||
}}
|
||||
/>
|
||||
}
|
||||
onSubmit={onSubmit}
|
||||
onCancel={onCancel}
|
||||
nonEditModeContent={
|
||||
<NoEditModeContainer>
|
||||
<ChipComponent id={id} name={inputValue} picture={picture} />
|
||||
|
||||
@ -31,6 +31,10 @@ export function useLeaveTableFocus() {
|
||||
.getLoadable(currentHotkeysScopeState)
|
||||
.valueOrThrow();
|
||||
|
||||
if (isSomeInputInEditMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSoftFocusActive && !isSomeInputInEditMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user