Refactor Editable Cell (#191)
This commit is contained in:
@ -1,7 +1,6 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import type { Meta, StoryObj } from '@storybook/react';
|
import type { Meta, StoryObj } from '@storybook/react';
|
||||||
|
|
||||||
import { CellBaseContainer } from '@/ui/components/editable-cell/CellBaseContainer';
|
|
||||||
import { getRenderWrapperForComponent } from '~/testing/renderWrappers';
|
import { getRenderWrapperForComponent } from '~/testing/renderWrappers';
|
||||||
|
|
||||||
import { CellCommentChip } from '../CellCommentChip';
|
import { CellCommentChip } from '../CellCommentChip';
|
||||||
@ -46,10 +45,8 @@ export const TooManyComments: Story = {
|
|||||||
export const InCellDefault: Story = {
|
export const InCellDefault: Story = {
|
||||||
render: getRenderWrapperForComponent(
|
render: getRenderWrapperForComponent(
|
||||||
<TestCellContainer>
|
<TestCellContainer>
|
||||||
<CellBaseContainer>
|
<StyledFakeCellText>Fake short text</StyledFakeCellText>
|
||||||
<StyledFakeCellText>Fake short text</StyledFakeCellText>
|
<CellCommentChip count={12} />
|
||||||
<CellCommentChip count={12} />
|
|
||||||
</CellBaseContainer>
|
|
||||||
</TestCellContainer>,
|
</TestCellContainer>,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
@ -57,12 +54,10 @@ export const InCellDefault: Story = {
|
|||||||
export const InCellOverlappingBlur: Story = {
|
export const InCellOverlappingBlur: Story = {
|
||||||
render: getRenderWrapperForComponent(
|
render: getRenderWrapperForComponent(
|
||||||
<TestCellContainer>
|
<TestCellContainer>
|
||||||
<CellBaseContainer>
|
<StyledFakeCellText>
|
||||||
<StyledFakeCellText>
|
Fake long text to demonstrate blur effect
|
||||||
Fake long text to demonstrate blur effect
|
</StyledFakeCellText>
|
||||||
</StyledFakeCellText>
|
<CellCommentChip count={12} />
|
||||||
<CellCommentChip count={12} />
|
|
||||||
</CellBaseContainer>
|
|
||||||
</TestCellContainer>,
|
</TestCellContainer>,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
import { useOpenCommentRightDrawer } from '@/comments/hooks/useOpenCommentRightDrawer';
|
||||||
import EditableChip from '@/ui/components/editable-cell/EditableChip';
|
import EditableChip from '@/ui/components/editable-cell/types/EditableChip';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
|
|
||||||
import { Company } from '../interfaces/company.interface';
|
import { Company } from '../interfaces/company.interface';
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CellCommentChip } from '@/comments/components/comments/CellCommentChip';
|
import { CellCommentChip } from '@/comments/components/comments/CellCommentChip';
|
||||||
import { EditableDoubleText } from '@/ui/components/editable-cell/EditableDoubleText';
|
import { EditableDoubleText } from '@/ui/components/editable-cell/types/EditableDoubleText';
|
||||||
|
|
||||||
import { PersonChip } from './PersonChip';
|
import { PersonChip } from './PersonChip';
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import {
|
|||||||
} from '@/companies/interfaces/company.interface';
|
} from '@/companies/interfaces/company.interface';
|
||||||
import { SearchConfigType } from '@/search/interfaces/interface';
|
import { SearchConfigType } from '@/search/interfaces/interface';
|
||||||
import { SEARCH_COMPANY_QUERY } from '@/search/services/search';
|
import { SEARCH_COMPANY_QUERY } from '@/search/services/search';
|
||||||
import { EditableRelation } from '@/ui/components/editable-cell/EditableRelation';
|
import { EditableRelation } from '@/ui/components/editable-cell/types/EditableRelation';
|
||||||
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
import { getLogoUrlFromDomainName } from '@/utils/utils';
|
||||||
import {
|
import {
|
||||||
QueryMode,
|
QueryMode,
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
|
||||||
import { CellBaseContainer } from '@/ui/components/editable-cell/CellBaseContainer';
|
|
||||||
import { CellEditModeContainer } from '@/ui/components/editable-cell/CellEditModeContainer';
|
|
||||||
import { DoubleTextInput } from '@/ui/components/inputs/DoubleTextInput';
|
import { DoubleTextInput } from '@/ui/components/inputs/DoubleTextInput';
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
||||||
|
|
||||||
@ -43,16 +41,12 @@ export function PeopleCompanyCreateCell({
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CellBaseContainer ref={containerRef}>
|
<DoubleTextInput
|
||||||
<CellEditModeContainer editModeVerticalPosition="over">
|
leftValue={companyDomainName}
|
||||||
<DoubleTextInput
|
rightValue={companyName}
|
||||||
leftValue={companyDomainName}
|
leftValuePlaceholder="URL"
|
||||||
rightValue={companyName}
|
rightValuePlaceholder="Name"
|
||||||
leftValuePlaceholder="URL"
|
onChange={handleDoubleTextChange}
|
||||||
rightValuePlaceholder="Name"
|
/>
|
||||||
onChange={handleDoubleTextChange}
|
|
||||||
/>
|
|
||||||
</CellEditModeContainer>
|
|
||||||
</CellBaseContainer>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
export const CellBaseContainer = styled.div`
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
height: 32px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
`;
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { overlayBackground } from '../../layout/styles/themes';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
|
||||||
};
|
|
||||||
|
|
||||||
export const CellEditModeContainer = styled.div<OwnProps>`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
padding-left: ${(props) => props.theme.spacing(2)};
|
|
||||||
padding-right: ${(props) => props.theme.spacing(2)};
|
|
||||||
margin-left: -2px;
|
|
||||||
position: absolute;
|
|
||||||
left: ${(props) =>
|
|
||||||
props.editModeHorizontalAlign === 'right' ? 'auto' : '0'};
|
|
||||||
right: ${(props) =>
|
|
||||||
props.editModeHorizontalAlign === 'right' ? '0' : 'auto'};
|
|
||||||
top: ${(props) => (props.editModeVerticalPosition === 'over' ? '0' : '100%')};
|
|
||||||
|
|
||||||
border: 1px solid ${(props) => props.theme.primaryBorder};
|
|
||||||
z-index: 1;
|
|
||||||
border-radius: 4px;
|
|
||||||
${overlayBackground}
|
|
||||||
`;
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
export const CellNormalModeContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
padding-left: ${(props) => props.theme.spacing(2)};
|
|
||||||
padding-right: ${(props) => props.theme.spacing(2)};
|
|
||||||
`;
|
|
||||||
@ -1,12 +1,23 @@
|
|||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
||||||
|
|
||||||
import { CellBaseContainer } from './CellBaseContainer';
|
import { EditableCellDisplayMode } from './EditableCellDisplayMode';
|
||||||
import { CellNormalModeContainer } from './CellNormalModeContainer';
|
|
||||||
import { EditableCellEditMode } from './EditableCellEditMode';
|
import { EditableCellEditMode } from './EditableCellEditMode';
|
||||||
|
|
||||||
|
export const CellBaseContainer = styled.div`
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 32px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
editModeContent: ReactElement;
|
editModeContent: ReactElement;
|
||||||
nonEditModeContent: ReactElement;
|
nonEditModeContent: ReactElement;
|
||||||
@ -42,16 +53,15 @@ export function EditableCell({
|
|||||||
<CellBaseContainer onClick={handleOnClick}>
|
<CellBaseContainer onClick={handleOnClick}>
|
||||||
{isEditMode ? (
|
{isEditMode ? (
|
||||||
<EditableCellEditMode
|
<EditableCellEditMode
|
||||||
editModeContent={editModeContent}
|
|
||||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||||
editModeVerticalPosition={editModeVerticalPosition}
|
editModeVerticalPosition={editModeVerticalPosition}
|
||||||
isEditMode={isEditMode}
|
isEditMode={isEditMode}
|
||||||
onOutsideClick={onOutsideClick}
|
onOutsideClick={onOutsideClick}
|
||||||
/>
|
>
|
||||||
|
{editModeContent}
|
||||||
|
</EditableCellEditMode>
|
||||||
) : (
|
) : (
|
||||||
<CellNormalModeContainer>
|
<EditableCellDisplayMode>{nonEditModeContent}</EditableCellDisplayMode>
|
||||||
<>{nonEditModeContent}</>
|
|
||||||
</CellNormalModeContainer>
|
|
||||||
)}
|
)}
|
||||||
</CellBaseContainer>
|
</CellBaseContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
import { ReactElement } from 'react';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
|
export const EditableCellNormalModeOuterContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
padding-left: ${(props) => props.theme.spacing(2)};
|
||||||
|
padding-right: ${(props) => props.theme.spacing(2)};
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const EditableCellNormalModeInnerContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
`;
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
children: ReactElement;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function EditableCellDisplayMode({ children }: OwnProps) {
|
||||||
|
return (
|
||||||
|
<EditableCellNormalModeOuterContainer>
|
||||||
|
<EditableCellNormalModeInnerContainer>
|
||||||
|
{children}
|
||||||
|
</EditableCellNormalModeInnerContainer>
|
||||||
|
</EditableCellNormalModeOuterContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
@ -1,16 +1,35 @@
|
|||||||
import { ReactElement, useMemo, useRef } from 'react';
|
import { ReactElement, useMemo, useRef } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
import { useHotkeys } from 'react-hotkeys-hook';
|
||||||
|
import styled from '@emotion/styled';
|
||||||
import { useRecoilState } from 'recoil';
|
import { useRecoilState } from 'recoil';
|
||||||
|
|
||||||
import { debounce } from '@/utils/debounce';
|
import { debounce } from '@/utils/debounce';
|
||||||
|
|
||||||
import { useListenClickOutsideArrayOfRef } from '../../hooks/useListenClickOutsideArrayOfRef';
|
import { useListenClickOutsideArrayOfRef } from '../../hooks/useListenClickOutsideArrayOfRef';
|
||||||
|
import { overlayBackground } from '../../layout/styles/themes';
|
||||||
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
||||||
|
|
||||||
import { CellEditModeContainer } from './CellEditModeContainer';
|
export const EditableCellEditModeContainer = styled.div<OwnProps>`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
min-width: calc(100% + 20px);
|
||||||
|
min-height: 100%;
|
||||||
|
margin-left: -2px;
|
||||||
|
position: absolute;
|
||||||
|
left: ${(props) =>
|
||||||
|
props.editModeHorizontalAlign === 'right' ? 'auto' : '0'};
|
||||||
|
right: ${(props) =>
|
||||||
|
props.editModeHorizontalAlign === 'right' ? '0' : 'auto'};
|
||||||
|
top: ${(props) => (props.editModeVerticalPosition === 'over' ? '0' : '100%')};
|
||||||
|
|
||||||
|
border: 1px solid ${(props) => props.theme.primaryBorder};
|
||||||
|
z-index: 1;
|
||||||
|
border-radius: 4px;
|
||||||
|
${overlayBackground}
|
||||||
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
editModeContent: ReactElement;
|
children: ReactElement;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
editModeVerticalPosition?: 'over' | 'below';
|
||||||
isEditMode?: boolean;
|
isEditMode?: boolean;
|
||||||
@ -21,7 +40,7 @@ type OwnProps = {
|
|||||||
export function EditableCellEditMode({
|
export function EditableCellEditMode({
|
||||||
editModeHorizontalAlign,
|
editModeHorizontalAlign,
|
||||||
editModeVerticalPosition,
|
editModeVerticalPosition,
|
||||||
editModeContent,
|
children,
|
||||||
isEditMode,
|
isEditMode,
|
||||||
onOutsideClick,
|
onOutsideClick,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
@ -77,13 +96,13 @@ export function EditableCellEditMode({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<CellEditModeContainer
|
<EditableCellEditModeContainer
|
||||||
data-testid="editable-cell-edit-mode-container"
|
data-testid="editable-cell-edit-mode-container"
|
||||||
ref={wrapperRef}
|
ref={wrapperRef}
|
||||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||||
editModeVerticalPosition={editModeVerticalPosition}
|
editModeVerticalPosition={editModeVerticalPosition}
|
||||||
>
|
>
|
||||||
{editModeContent}
|
{children}
|
||||||
</CellEditModeContainer>
|
</EditableCellEditModeContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,67 +0,0 @@
|
|||||||
import { ReactElement } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
import { useRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
|
||||||
|
|
||||||
import { CellBaseContainer } from './CellBaseContainer';
|
|
||||||
import { EditableCellMenuEditMode } from './EditableCellMenuEditMode';
|
|
||||||
|
|
||||||
const EditableCellMenuNormalModeContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: calc(100% - ${(props) => props.theme.spacing(5)});
|
|
||||||
height: 100%;
|
|
||||||
overflow: hidden;
|
|
||||||
`;
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
editModeContent: ReactElement;
|
|
||||||
nonEditModeContent: ReactElement;
|
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
|
||||||
isEditMode?: boolean;
|
|
||||||
isCreateMode?: boolean;
|
|
||||||
onOutsideClick?: () => void;
|
|
||||||
onInsideClick?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
export function EditableCellMenu({
|
|
||||||
editModeContent,
|
|
||||||
nonEditModeContent,
|
|
||||||
editModeHorizontalAlign = 'left',
|
|
||||||
editModeVerticalPosition = 'over',
|
|
||||||
isEditMode = false,
|
|
||||||
onOutsideClick,
|
|
||||||
onInsideClick,
|
|
||||||
}: OwnProps) {
|
|
||||||
const [isSomeInputInEditMode, setIsSomeInputInEditMode] = useRecoilState(
|
|
||||||
isSomeInputInEditModeState,
|
|
||||||
);
|
|
||||||
|
|
||||||
function handleOnClick() {
|
|
||||||
if (!isSomeInputInEditMode) {
|
|
||||||
onInsideClick?.();
|
|
||||||
setIsSomeInputInEditMode(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CellBaseContainer onClick={handleOnClick}>
|
|
||||||
<EditableCellMenuNormalModeContainer>
|
|
||||||
{nonEditModeContent}
|
|
||||||
</EditableCellMenuNormalModeContainer>
|
|
||||||
{isEditMode && (
|
|
||||||
<EditableCellMenuEditMode
|
|
||||||
editModeContent={editModeContent}
|
|
||||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
|
||||||
editModeVerticalPosition={editModeVerticalPosition}
|
|
||||||
isEditMode={isEditMode}
|
|
||||||
onOutsideClick={onOutsideClick}
|
|
||||||
onInsideClick={onInsideClick}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</CellBaseContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,88 +0,0 @@
|
|||||||
import { ReactElement, useMemo, useRef } from 'react';
|
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import { useRecoilState } from 'recoil';
|
|
||||||
|
|
||||||
import { debounce } from '@/utils/debounce';
|
|
||||||
|
|
||||||
import { useListenClickOutsideArrayOfRef } from '../../hooks/useListenClickOutsideArrayOfRef';
|
|
||||||
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
|
||||||
|
|
||||||
import { EditableCellMenuEditModeContainer } from './EditableCellMenuEditModeContainer';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
editModeContent: ReactElement;
|
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
|
||||||
isEditMode?: boolean;
|
|
||||||
onOutsideClick?: () => void;
|
|
||||||
onInsideClick?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function EditableCellMenuEditMode({
|
|
||||||
editModeHorizontalAlign,
|
|
||||||
editModeVerticalPosition,
|
|
||||||
editModeContent,
|
|
||||||
isEditMode,
|
|
||||||
onOutsideClick,
|
|
||||||
}: OwnProps) {
|
|
||||||
const wrapperRef = useRef(null);
|
|
||||||
|
|
||||||
const [, setIsSomeInputInEditMode] = useRecoilState(
|
|
||||||
isSomeInputInEditModeState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const debouncedSetIsSomeInputInEditMode = useMemo(() => {
|
|
||||||
return debounce(setIsSomeInputInEditMode, 20);
|
|
||||||
}, [setIsSomeInputInEditMode]);
|
|
||||||
|
|
||||||
useListenClickOutsideArrayOfRef([wrapperRef], () => {
|
|
||||||
if (isEditMode) {
|
|
||||||
debouncedSetIsSomeInputInEditMode(false);
|
|
||||||
onOutsideClick?.();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
'esc',
|
|
||||||
() => {
|
|
||||||
if (isEditMode) {
|
|
||||||
onOutsideClick?.();
|
|
||||||
|
|
||||||
debouncedSetIsSomeInputInEditMode(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
preventDefault: true,
|
|
||||||
enableOnContentEditable: true,
|
|
||||||
enableOnFormTags: true,
|
|
||||||
},
|
|
||||||
[isEditMode, onOutsideClick, debouncedSetIsSomeInputInEditMode],
|
|
||||||
);
|
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
'enter',
|
|
||||||
() => {
|
|
||||||
if (isEditMode) {
|
|
||||||
onOutsideClick?.();
|
|
||||||
|
|
||||||
debouncedSetIsSomeInputInEditMode(false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
preventDefault: true,
|
|
||||||
enableOnContentEditable: true,
|
|
||||||
enableOnFormTags: true,
|
|
||||||
},
|
|
||||||
[isEditMode, onOutsideClick, debouncedSetIsSomeInputInEditMode],
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<EditableCellMenuEditModeContainer
|
|
||||||
ref={wrapperRef}
|
|
||||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
|
||||||
editModeVerticalPosition={editModeVerticalPosition}
|
|
||||||
>
|
|
||||||
{editModeContent}
|
|
||||||
</EditableCellMenuEditModeContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { overlayBackground } from '../../layout/styles/themes';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
|
||||||
editModeVerticalPosition?: 'over' | 'below';
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: refactor
|
|
||||||
export const EditableCellMenuEditModeContainer = styled.div<OwnProps>`
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: ${(props) =>
|
|
||||||
props.editModeHorizontalAlign === 'right' ? 'auto' : '-1px'};
|
|
||||||
right: ${(props) =>
|
|
||||||
props.editModeHorizontalAlign === 'right' ? '0' : 'auto'};
|
|
||||||
top: ${(props) => (props.editModeVerticalPosition === 'over' ? '0' : '100%')};
|
|
||||||
|
|
||||||
border: 1px solid ${(props) => props.theme.primaryBorder};
|
|
||||||
z-index: 1;
|
|
||||||
border-radius: 4px;
|
|
||||||
${overlayBackground}
|
|
||||||
`;
|
|
||||||
@ -2,10 +2,9 @@ import { ChangeEvent, ComponentType, useRef, useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CellCommentChip } from '@/comments/components/comments/CellCommentChip';
|
import { CellCommentChip } from '@/comments/components/comments/CellCommentChip';
|
||||||
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
|
|
||||||
import { textInputStyle } from '../../layout/styles/themes';
|
import { EditableCell } from '../EditableCell';
|
||||||
|
|
||||||
import { EditableCell } from './EditableCell';
|
|
||||||
|
|
||||||
export type EditableChipProps = {
|
export type EditableChipProps = {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -30,11 +29,6 @@ const StyledInplaceInput = styled.input`
|
|||||||
const StyledInplaceShow = styled.div`
|
const StyledInplaceShow = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
font-weight: 'bold';
|
|
||||||
color: props.theme.text20;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function EditableChip({
|
function EditableChip({
|
||||||
@ -3,9 +3,8 @@ import styled from '@emotion/styled';
|
|||||||
|
|
||||||
import { humanReadableDate } from '@/utils/utils';
|
import { humanReadableDate } from '@/utils/utils';
|
||||||
|
|
||||||
import DatePicker from '../form/DatePicker';
|
import DatePicker from '../../form/DatePicker';
|
||||||
|
import { EditableCell } from '../EditableCell';
|
||||||
import { EditableCell } from './EditableCell';
|
|
||||||
|
|
||||||
export type EditableDateProps = {
|
export type EditableDateProps = {
|
||||||
value: Date;
|
value: Date;
|
||||||
@ -16,6 +15,7 @@ export type EditableDateProps = {
|
|||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin: 0px ${(props) => props.theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type StyledCalendarContainerProps = {
|
export type StyledCalendarContainerProps = {
|
||||||
@ -78,9 +78,7 @@ export function EditableDate({
|
|||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
}
|
}
|
||||||
nonEditModeContent={
|
nonEditModeContent={
|
||||||
<StyledContainer>
|
<div>{inputValue && humanReadableDate(inputValue)}</div>
|
||||||
<div>{inputValue && humanReadableDate(inputValue)}</div>
|
|
||||||
</StyledContainer>
|
|
||||||
}
|
}
|
||||||
></EditableCell>
|
></EditableCell>
|
||||||
);
|
);
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import { ChangeEvent, ReactElement, useRef, useState } from 'react';
|
import { ChangeEvent, ReactElement, useRef, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { textInputStyle } from '../../layout/styles/themes';
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
|
|
||||||
import { EditableCell } from './EditableCell';
|
import { EditableCell } from '../EditableCell';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
firstValue: string;
|
firstValue: string;
|
||||||
@ -28,6 +28,7 @@ const StyledContainer = styled.div`
|
|||||||
const StyledEditInplaceInput = styled.input`
|
const StyledEditInplaceInput = styled.input`
|
||||||
width: 45%;
|
width: 45%;
|
||||||
height: 18px;
|
height: 18px;
|
||||||
|
margin: 0px ${(props) => props.theme.spacing(2)};
|
||||||
|
|
||||||
${textInputStyle}
|
${textInputStyle}
|
||||||
`;
|
`;
|
||||||
@ -2,9 +2,10 @@ import { ChangeEvent, MouseEvent, useRef, useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js';
|
import { isValidPhoneNumber, parsePhoneNumber } from 'libphonenumber-js';
|
||||||
|
|
||||||
import Link from '../link/Link';
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
|
|
||||||
import { EditableCell } from './EditableCell';
|
import Link from '../../link/Link';
|
||||||
|
import { EditableCell } from '../EditableCell';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -19,13 +20,8 @@ type StyledEditModeProps = {
|
|||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
const StyledEditInplaceInput = styled.input<StyledEditModeProps>`
|
const StyledEditInplaceInput = styled.input<StyledEditModeProps>`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border: none;
|
margin: 0px ${(props) => props.theme.spacing(2)};
|
||||||
outline: none;
|
${textInputStyle}
|
||||||
|
|
||||||
&::placeholder {
|
|
||||||
font-weight: bold;
|
|
||||||
color: ${(props) => props.theme.text20};
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function EditablePhone({ value, placeholder, changeHandler }: OwnProps) {
|
export function EditablePhone({ value, placeholder, changeHandler }: OwnProps) {
|
||||||
@ -5,22 +5,19 @@ import { useRecoilState } from 'recoil';
|
|||||||
|
|
||||||
import { SearchConfigType } from '@/search/interfaces/interface';
|
import { SearchConfigType } from '@/search/interfaces/interface';
|
||||||
import { useSearch } from '@/search/services/search';
|
import { useSearch } from '@/search/services/search';
|
||||||
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
|
import { isSomeInputInEditModeState } from '@/ui/tables/states/isSomeInputInEditModeState';
|
||||||
import { AnyEntity } from '@/utils/interfaces/generic.interface';
|
import { AnyEntity } from '@/utils/interfaces/generic.interface';
|
||||||
import { isDefined } from '@/utils/type-guards/isDefined';
|
import { isDefined } from '@/utils/type-guards/isDefined';
|
||||||
import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
|
import { isNonEmptyString } from '@/utils/type-guards/isNonEmptyString';
|
||||||
|
|
||||||
import { textInputStyle } from '../../layout/styles/themes';
|
import { EditableCell } from '../EditableCell';
|
||||||
import { isSomeInputInEditModeState } from '../../tables/states/isSomeInputInEditModeState';
|
import { HoverableMenuItem } from '../HoverableMenuItem';
|
||||||
|
|
||||||
import { CellNormalModeContainer } from './CellNormalModeContainer';
|
|
||||||
import { EditableCellMenu } from './EditableCellMenu';
|
|
||||||
import { EditableRelationCreateButton } from './EditableRelationCreateButton';
|
import { EditableRelationCreateButton } from './EditableRelationCreateButton';
|
||||||
import { HoverableMenuItem } from './HoverableMenuItem';
|
|
||||||
|
|
||||||
const StyledEditModeContainer = styled.div`
|
const StyledEditModeContainer = styled.div`
|
||||||
width: 200px;
|
width: 200px;
|
||||||
// margin-left: calc(-1 * ${(props) => props.theme.spacing(2)});
|
|
||||||
// margin-right: calc(-1 * ${(props) => props.theme.spacing(2)});
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledEditModeSelectedContainer = styled.div`
|
const StyledEditModeSelectedContainer = styled.div`
|
||||||
@ -144,7 +141,7 @@ export function EditableRelation<
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<EditableCellMenu
|
<EditableCell
|
||||||
editModeHorizontalAlign={editModeHorizontalAlign}
|
editModeHorizontalAlign={editModeHorizontalAlign}
|
||||||
isEditMode={isEditMode}
|
isEditMode={isEditMode}
|
||||||
onOutsideClick={() => setIsEditMode(false)}
|
onOutsideClick={() => setIsEditMode(false)}
|
||||||
@ -207,13 +204,13 @@ export function EditableRelation<
|
|||||||
</StyledEditModeContainer>
|
</StyledEditModeContainer>
|
||||||
}
|
}
|
||||||
nonEditModeContent={
|
nonEditModeContent={
|
||||||
<CellNormalModeContainer>
|
<>
|
||||||
{relation ? (
|
{relation ? (
|
||||||
<ChipComponent {...chipComponentPropsMapper(relation)} />
|
<ChipComponent {...chipComponentPropsMapper(relation)} />
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
)}
|
)}
|
||||||
</CellNormalModeContainer>
|
</>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
@ -16,9 +16,4 @@ export const EditableRelationCreateButton = styled.button`
|
|||||||
height: 31px;
|
height: 31px;
|
||||||
background: none;
|
background: none;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
// :hover {
|
|
||||||
// background: rgba(0, 0, 0, 0.04);
|
|
||||||
// color: ${(props) => props.theme.text100};
|
|
||||||
// }
|
|
||||||
// margin-bottom: calc(${(props) => props.theme.spacing(1)} / 2);
|
|
||||||
`;
|
`;
|
||||||
@ -1,9 +1,9 @@
|
|||||||
import { ChangeEvent, useRef, useState } from 'react';
|
import { ChangeEvent, useRef, useState } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { textInputStyle } from '../../layout/styles/themes';
|
import { textInputStyle } from '@/ui/layout/styles/themes';
|
||||||
|
|
||||||
import { EditableCell } from './EditableCell';
|
import { EditableCell } from '../EditableCell';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
@ -19,6 +19,7 @@ type StyledEditModeProps = {
|
|||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
const StyledInplaceInput = styled.input<StyledEditModeProps>`
|
const StyledInplaceInput = styled.input<StyledEditModeProps>`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
margin: 0px ${(props) => props.theme.spacing(2)};
|
||||||
${textInputStyle}
|
${textInputStyle}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -18,9 +18,9 @@ import {
|
|||||||
} from '@/people/components/PersonChip';
|
} from '@/people/components/PersonChip';
|
||||||
import { SearchConfigType } from '@/search/interfaces/interface';
|
import { SearchConfigType } from '@/search/interfaces/interface';
|
||||||
import { SEARCH_USER_QUERY } from '@/search/services/search';
|
import { SEARCH_USER_QUERY } from '@/search/services/search';
|
||||||
import { EditableDate } from '@/ui/components/editable-cell/EditableDate';
|
import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate';
|
||||||
import { EditableRelation } from '@/ui/components/editable-cell/EditableRelation';
|
import { EditableRelation } from '@/ui/components/editable-cell/types/EditableRelation';
|
||||||
import { EditableText } from '@/ui/components/editable-cell/EditableText';
|
import { EditableText } from '@/ui/components/editable-cell/types/EditableText';
|
||||||
import { CheckboxCell } from '@/ui/components/table/CheckboxCell';
|
import { CheckboxCell } from '@/ui/components/table/CheckboxCell';
|
||||||
import { ColumnHead } from '@/ui/components/table/ColumnHead';
|
import { ColumnHead } from '@/ui/components/table/ColumnHead';
|
||||||
import { SelectAllCheckbox } from '@/ui/components/table/SelectAllCheckbox';
|
import { SelectAllCheckbox } from '@/ui/components/table/SelectAllCheckbox';
|
||||||
|
|||||||
@ -13,9 +13,9 @@ import { EditablePeopleFullName } from '@/people/components/EditablePeopleFullNa
|
|||||||
import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell';
|
import { PeopleCompanyCell } from '@/people/components/PeopleCompanyCell';
|
||||||
import { Person } from '@/people/interfaces/person.interface';
|
import { Person } from '@/people/interfaces/person.interface';
|
||||||
import { updatePerson } from '@/people/services';
|
import { updatePerson } from '@/people/services';
|
||||||
import { EditableDate } from '@/ui/components/editable-cell/EditableDate';
|
import { EditableDate } from '@/ui/components/editable-cell/types/EditableDate';
|
||||||
import { EditablePhone } from '@/ui/components/editable-cell/EditablePhone';
|
import { EditablePhone } from '@/ui/components/editable-cell/types/EditablePhone';
|
||||||
import { EditableText } from '@/ui/components/editable-cell/EditableText';
|
import { EditableText } from '@/ui/components/editable-cell/types/EditableText';
|
||||||
import { CheckboxCell } from '@/ui/components/table/CheckboxCell';
|
import { CheckboxCell } from '@/ui/components/table/CheckboxCell';
|
||||||
import { ColumnHead } from '@/ui/components/table/ColumnHead';
|
import { ColumnHead } from '@/ui/components/table/ColumnHead';
|
||||||
import { SelectAllCheckbox } from '@/ui/components/table/SelectAllCheckbox';
|
import { SelectAllCheckbox } from '@/ui/components/table/SelectAllCheckbox';
|
||||||
|
|||||||
Reference in New Issue
Block a user