Clean and re-organize post table refactoring (#1000)

* Clean and re-organize post table refactoring

* Fix tests
This commit is contained in:
Charles Bochet
2023-07-30 18:26:32 -07:00
committed by GitHub
parent 86a2d67efd
commit ade5e52e55
336 changed files with 638 additions and 2757 deletions

View File

@ -2,7 +2,7 @@ import { useCallback } from 'react';
import styled from '@emotion/styled';
import { useSetRecoilState } from 'recoil';
import { Checkbox } from '@/ui/input/components/Checkbox';
import { Checkbox } from '@/ui/input/checkbox/components/Checkbox';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
import { contextMenuPositionState } from '../states/contextMenuPositionState';

View File

@ -1,13 +1,12 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { TableColumn } from '@/people/table/components/peopleColumns';
import { SelectedSortType, SortType } from '@/ui/filter-n-sort/types/interface';
import { useListenClickOutside } from '@/ui/hooks/useListenClickOutside';
import { useListenClickOutside } from '@/ui/utilities/click-outside/hooks/useListenClickOutside';
import { useIsPageLoading } from '../../hooks/useIsPageLoading';
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { EntityUpdateMutationHookContext } from '../states/EntityUpdateMutationHookContext';
import { TableHeader } from '../table-header/components/TableHeader';
import { EntityTableBody } from './EntityTableBody';
@ -85,20 +84,20 @@ const StyledTableWrapper = styled.div`
`;
type OwnProps<SortField> = {
columns: Array<TableColumn>;
viewName: string;
viewIcon?: React.ReactNode;
availableSorts?: Array<SortType<SortField>>;
onSortsUpdate?: (sorts: Array<SelectedSortType<SortField>>) => void;
onRowSelectionChange?: (rowSelection: string[]) => void;
useUpdateEntityMutation: any;
};
export function EntityTable<SortField>({
columns,
viewName,
viewIcon,
availableSorts,
onSortsUpdate,
useUpdateEntityMutation,
}: OwnProps<SortField>) {
const tableBodyRef = React.useRef<HTMLDivElement>(null);
@ -113,28 +112,24 @@ export function EntityTable<SortField>({
},
});
const isPageLoading = useIsPageLoading();
if (isPageLoading) {
return null;
}
return (
<StyledTableWithHeader>
<StyledTableContainer ref={tableBodyRef}>
<TableHeader
viewName={viewName}
viewIcon={viewIcon}
availableSorts={availableSorts}
onSortsUpdate={onSortsUpdate}
/>
<StyledTableWrapper>
<StyledTable>
<EntityTableHeader columns={columns} />
<EntityTableBody columns={columns} />
</StyledTable>
</StyledTableWrapper>
</StyledTableContainer>
</StyledTableWithHeader>
<EntityUpdateMutationHookContext.Provider value={useUpdateEntityMutation}>
<StyledTableWithHeader>
<StyledTableContainer ref={tableBodyRef}>
<TableHeader
viewName={viewName}
viewIcon={viewIcon}
availableSorts={availableSorts}
onSortsUpdate={onSortsUpdate}
/>
<StyledTableWrapper>
<StyledTable>
<EntityTableHeader />
<EntityTableBody />
</StyledTable>
</StyledTableWrapper>
</StyledTableContainer>
</StyledTableWithHeader>
</EntityUpdateMutationHookContext.Provider>
);
}

View File

@ -1,6 +1,5 @@
import { useRecoilValue } from 'recoil';
import { TableColumn } from '@/people/table/components/peopleColumns';
import { isNavbarSwitchingSizeState } from '@/ui/layout/states/isNavbarSwitchingSizeState';
import { isFetchingEntityTableDataState } from '../states/isFetchingEntityTableDataState';
@ -10,7 +9,7 @@ import { tableRowIdsState } from '../states/tableRowIdsState';
import { EntityTableRow } from './EntityTableRow';
export function EntityTableBody({ columns }: { columns: Array<TableColumn> }) {
export function EntityTableBody() {
const rowIds = useRecoilValue(tableRowIdsState);
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
@ -28,7 +27,7 @@ export function EntityTableBody({ columns }: { columns: Array<TableColumn> }) {
{rowIds.map((rowId, index) => (
<RowIdContext.Provider value={rowId} key={rowId}>
<RowIndexContext.Provider value={index}>
<EntityTableRow columns={columns} rowId={rowId} />
<EntityTableRow rowId={rowId} />
</RowIndexContext.Provider>
</RowIdContext.Provider>
))}

View File

@ -1,36 +0,0 @@
import { useRecoilValue } from 'recoil';
import { isNavbarSwitchingSizeState } from '@/ui/layout/states/isNavbarSwitchingSizeState';
import { isFetchingEntityTableDataState } from '../states/isFetchingEntityTableDataState';
import { RowIdContext } from '../states/RowIdContext';
import { RowIndexContext } from '../states/RowIndexContext';
import { tableRowIdsState } from '../states/tableRowIdsState';
import { EntityTableRow } from './EntityTableRowV2';
export function EntityTableBody() {
const rowIds = useRecoilValue(tableRowIdsState);
const isNavbarSwitchingSize = useRecoilValue(isNavbarSwitchingSizeState);
const isFetchingEntityTableData = useRecoilValue(
isFetchingEntityTableDataState,
);
if (isFetchingEntityTableData || isNavbarSwitchingSize) {
return null;
}
return (
<tbody>
{rowIds.map((rowId, index) => (
<RowIdContext.Provider value={rowId} key={rowId}>
<RowIndexContext.Provider value={index}>
<EntityTableRow rowId={rowId} />
</RowIndexContext.Provider>
</RowIdContext.Provider>
))}
</tbody>
);
}

View File

@ -1,19 +1,15 @@
import { useContext } from 'react';
import { useSetRecoilState } from 'recoil';
import { RecoilScope } from '../../recoil-scope/components/RecoilScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { GenericEditableCell } from '../editable-cell/components/GenericEditableCell';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
import { ColumnIndexContext } from '../states/ColumnIndexContext';
import { contextMenuPositionState } from '../states/contextMenuPositionState';
import { ViewFieldContext } from '../states/ViewFieldContext';
export function EntityTableCell({
cellIndex,
children,
size,
}: {
size: number;
cellIndex: number;
children: React.ReactNode;
}) {
export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const { setCurrentRowSelected } = useCurrentRowSelected();
@ -29,18 +25,24 @@ export function EntityTableCell({
});
}
const viewField = useContext(ViewFieldContext);
if (!viewField) {
return null;
}
return (
<RecoilScope>
<ColumnIndexContext.Provider value={cellIndex}>
<td
onContextMenu={(event) => handleContextMenu(event)}
style={{
width: size,
minWidth: size,
maxWidth: size,
width: viewField.columnSize,
minWidth: viewField.columnSize,
maxWidth: viewField.columnSize,
}}
>
{children}
<GenericEditableCell viewField={viewField} />
</td>
</ColumnIndexContext.Provider>
</RecoilScope>

View File

@ -1,50 +0,0 @@
import { useContext } from 'react';
import { useSetRecoilState } from 'recoil';
import { GenericEditableCell } from '@/ui/table/components/GenericEditableCell';
import { RecoilScope } from '../../recoil-scope/components/RecoilScope';
import { useCurrentRowSelected } from '../hooks/useCurrentRowSelected';
import { ColumnIndexContext } from '../states/ColumnIndexContext';
import { contextMenuPositionState } from '../states/contextMenuPositionState';
import { ViewFieldContext } from '../states/ViewFieldContext';
export function EntityTableCell({ cellIndex }: { cellIndex: number }) {
const setContextMenuPosition = useSetRecoilState(contextMenuPositionState);
const { setCurrentRowSelected } = useCurrentRowSelected();
function handleContextMenu(event: React.MouseEvent) {
event.preventDefault();
setCurrentRowSelected(true);
setContextMenuPosition({
x: event.clientX,
y: event.clientY,
});
}
const viewField = useContext(ViewFieldContext);
if (!viewField) {
return null;
}
return (
<RecoilScope>
<ColumnIndexContext.Provider value={cellIndex}>
<td
onContextMenu={(event) => handleContextMenu(event)}
style={{
width: viewField.columnSize,
minWidth: viewField.columnSize,
maxWidth: viewField.columnSize,
}}
>
<GenericEditableCell viewField={viewField} />
</td>
</ColumnIndexContext.Provider>
</RecoilScope>
);
}

View File

@ -1,13 +1,13 @@
import { TableColumn } from '@/people/table/components/peopleColumns';
import { useRecoilValue } from 'recoil';
import { viewFieldsFamilyState } from '../states/viewFieldsState';
import { ColumnHead } from './ColumnHead';
import { SelectAllCheckbox } from './SelectAllCheckbox';
export function EntityTableHeader({
columns,
}: {
columns: Array<TableColumn>;
}) {
export function EntityTableHeader() {
const viewFields = useRecoilValue(viewFieldsFamilyState);
return (
<thead>
<tr>
@ -20,16 +20,19 @@ export function EntityTableHeader({
>
<SelectAllCheckbox />
</th>
{columns.map((column) => (
{viewFields.map((viewField) => (
<th
key={column.id.toString()}
key={viewField.columnOrder.toString()}
style={{
width: column.size,
minWidth: column.size,
maxWidth: column.size,
width: viewField.columnSize,
minWidth: viewField.columnSize,
maxWidth: viewField.columnSize,
}}
>
<ColumnHead viewName={column.title} viewIcon={column.icon} />
<ColumnHead
viewName={viewField.columnLabel}
viewIcon={viewField.columnIcon}
/>
</th>
))}
<th></th>

View File

@ -1,42 +0,0 @@
import { useRecoilValue } from 'recoil';
import { viewFieldsFamilyState } from '../states/viewFieldsState';
import { ColumnHead } from './ColumnHead';
import { SelectAllCheckbox } from './SelectAllCheckbox';
export function EntityTableHeader() {
const viewFields = useRecoilValue(viewFieldsFamilyState);
return (
<thead>
<tr>
<th
style={{
width: 30,
minWidth: 30,
maxWidth: 30,
}}
>
<SelectAllCheckbox />
</th>
{viewFields.map((viewField) => (
<th
key={viewField.columnOrder.toString()}
style={{
width: viewField.columnSize,
minWidth: viewField.columnSize,
maxWidth: viewField.columnSize,
}}
>
<ColumnHead
viewName={viewField.columnLabel}
viewIcon={viewField.columnIcon}
/>
</th>
))}
<th></th>
</tr>
</thead>
);
}

View File

@ -1,6 +1,8 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { TableColumn } from '@/people/table/components/peopleColumns';
import { ViewFieldContext } from '../states/ViewFieldContext';
import { viewFieldsFamilyState } from '../states/viewFieldsState';
import { CheckboxCell } from './CheckboxCell';
import { EntityTableCell } from './EntityTableCell';
@ -10,27 +12,22 @@ const StyledRow = styled.tr<{ selected: boolean }>`
props.selected ? props.theme.background.secondary : 'none'};
`;
export function EntityTableRow({
columns,
rowId,
}: {
columns: TableColumn[];
rowId: string;
}) {
export function EntityTableRow({ rowId }: { rowId: string }) {
const viewFields = useRecoilValue(viewFieldsFamilyState);
return (
<StyledRow data-testid={`row-id-${rowId}`} selected={false}>
<td>
<CheckboxCell />
</td>
{columns.map((column, columnIndex) => {
{viewFields.map((viewField, columnIndex) => {
return (
<EntityTableCell
key={column.id}
size={column.size}
cellIndex={columnIndex}
<ViewFieldContext.Provider
value={viewField}
key={viewField.columnOrder}
>
{column.cellComponent}
</EntityTableCell>
<EntityTableCell cellIndex={columnIndex} />
</ViewFieldContext.Provider>
);
})}
<td></td>

View File

@ -1,36 +0,0 @@
import styled from '@emotion/styled';
import { useRecoilValue } from 'recoil';
import { ViewFieldContext } from '../states/ViewFieldContext';
import { viewFieldsFamilyState } from '../states/viewFieldsState';
import { CheckboxCell } from './CheckboxCell';
import { EntityTableCell } from './EntityTableCellV2';
const StyledRow = styled.tr<{ selected: boolean }>`
background: ${(props) =>
props.selected ? props.theme.background.secondary : 'none'};
`;
export function EntityTableRow({ rowId }: { rowId: string }) {
const viewFields = useRecoilValue(viewFieldsFamilyState);
return (
<StyledRow data-testid={`row-id-${rowId}`} selected={false}>
<td>
<CheckboxCell />
</td>
{viewFields.map((viewField, columnIndex) => {
return (
<ViewFieldContext.Provider
value={viewField}
key={viewField.columnOrder}
>
<EntityTableCell cellIndex={columnIndex} />
</ViewFieldContext.Provider>
);
})}
<td></td>
</StyledRow>
);
}

View File

@ -1,135 +0,0 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { SelectedSortType, SortType } from '@/ui/filter-n-sort/types/interface';
import { useListenClickOutside } from '@/ui/hooks/useListenClickOutside';
import { useLeaveTableFocus } from '../hooks/useLeaveTableFocus';
import { useMapKeyboardToSoftFocus } from '../hooks/useMapKeyboardToSoftFocus';
import { EntityUpdateMutationHookContext } from '../states/EntityUpdateMutationHookContext';
import { TableHeader } from '../table-header/components/TableHeader';
import { EntityTableBody } from './EntityTableBodyV2';
import { EntityTableHeader } from './EntityTableHeaderV2';
const StyledTable = styled.table`
border-collapse: collapse;
border-radius: ${({ theme }) => theme.border.radius.sm};
border-spacing: 0;
margin-left: ${({ theme }) => theme.table.horizontalCellMargin};
margin-right: ${({ theme }) => theme.table.horizontalCellMargin};
table-layout: fixed;
width: calc(100% - ${({ theme }) => theme.table.horizontalCellMargin} * 2);
th {
border: 1px solid ${({ theme }) => theme.border.color.light};
border-collapse: collapse;
color: ${({ theme }) => theme.font.color.tertiary};
padding: 0;
text-align: left;
:last-child {
border-right-color: transparent;
}
:first-of-type {
border-left-color: transparent;
border-right-color: transparent;
}
:last-of-type {
min-width: 0;
width: 100%;
}
}
td {
border: 1px solid ${({ theme }) => theme.border.color.light};
border-collapse: collapse;
color: ${({ theme }) => theme.font.color.primary};
padding: 0;
text-align: left;
:last-child {
border-right-color: transparent;
}
:first-of-type {
border-left-color: transparent;
border-right-color: transparent;
}
:last-of-type {
min-width: 0;
width: 100%;
}
}
`;
const StyledTableWithHeader = styled.div`
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
`;
const StyledTableContainer = styled.div`
display: flex;
flex-direction: column;
height: 100%;
overflow: auto;
`;
const StyledTableWrapper = styled.div`
flex: 1;
overflow: auto;
`;
type OwnProps<SortField> = {
viewName: string;
viewIcon?: React.ReactNode;
availableSorts?: Array<SortType<SortField>>;
onSortsUpdate?: (sorts: Array<SelectedSortType<SortField>>) => void;
onRowSelectionChange?: (rowSelection: string[]) => void;
useUpdateEntityMutation: any;
};
export function EntityTable<SortField>({
viewName,
viewIcon,
availableSorts,
onSortsUpdate,
useUpdateEntityMutation,
}: OwnProps<SortField>) {
const tableBodyRef = React.useRef<HTMLDivElement>(null);
useMapKeyboardToSoftFocus();
const leaveTableFocus = useLeaveTableFocus();
useListenClickOutside({
refs: [tableBodyRef],
callback: () => {
leaveTableFocus();
},
});
return (
<EntityUpdateMutationHookContext.Provider value={useUpdateEntityMutation}>
<StyledTableWithHeader>
<StyledTableContainer ref={tableBodyRef}>
<TableHeader
viewName={viewName}
viewIcon={viewIcon}
availableSorts={availableSorts}
onSortsUpdate={onSortsUpdate}
/>
<StyledTableWrapper>
<StyledTable>
<EntityTableHeader />
<EntityTableBody />
</StyledTable>
</StyledTableWrapper>
</StyledTableContainer>
</StyledTableWithHeader>
</EntityUpdateMutationHookContext.Provider>
);
}

View File

@ -1,6 +1,6 @@
import styled from '@emotion/styled';
import { Checkbox } from '@/ui/input/components/Checkbox';
import { Checkbox } from '@/ui/input/checkbox/components/Checkbox';
import { useSelectAllRows } from '../hooks/useSelectAllRows';

View File

@ -1,7 +1,7 @@
import { ReactElement } from 'react';
import styled from '@emotion/styled';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { CellHotkeyScopeContext } from '../../states/CellHotkeyScopeContext';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';

View File

@ -1,7 +1,7 @@
import { ReactElement } from 'react';
import styled from '@emotion/styled';
import { overlayBackground } from '@/ui/themes/effects';
import { overlayBackground } from '@/ui/theme/constants/effects';
export const EditableCellEditModeContainer = styled.div<OwnProps>`
align-items: center;

View File

@ -1,7 +1,7 @@
import { PropsWithChildren } from 'react';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { isNonTextWritingKey } from '@/ui/hotkey/utils/isNonTextWritingKey';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { isNonTextWritingKey } from '@/ui/utilities/hotkey/utils/isNonTextWritingKey';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useEditableCell } from '../hooks/useEditableCell';

View File

@ -3,25 +3,24 @@ import {
ViewFieldMetadata,
} from '@/ui/table/types/ViewField';
import { isViewFieldChip } from '../types/guards/isViewFieldChip';
import { isViewFieldDate } from '../types/guards/isViewFieldDate';
import { isViewFieldDoubleText } from '../types/guards/isViewFieldDoubleText';
import { isViewFieldDoubleTextChip } from '../types/guards/isViewFieldDoubleTextChip';
import { isViewFieldNumber } from '../types/guards/isViewFieldNumber';
import { isViewFieldPhone } from '../types/guards/isViewFieldPhone';
import { isViewFieldRelation } from '../types/guards/isViewFieldRelation';
import { isViewFieldText } from '../types/guards/isViewFieldText';
import { isViewFieldURL } from '../types/guards/isViewFieldURL';
import { GenericEditableChipCell } from './GenericEditableChipCell';
import { GenericEditableDateCell } from './GenericEditableDateCell';
import { GenericEditableDoubleTextCell } from './GenericEditableDoubleTextCell';
import { GenericEditableDoubleTextChipCell } from './GenericEditableDoubleTextChipCell';
import { GenericEditableNumberCell } from './GenericEditableNumberCell';
import { GenericEditablePhoneCell } from './GenericEditablePhoneCell';
import { GenericEditableRelationCell } from './GenericEditableRelationCell';
import { GenericEditableTextCell } from './GenericEditableTextCell';
import { GenericEditableURLCell } from './GenericEditableURLCell';
import { isViewFieldChip } from '../../types/guards/isViewFieldChip';
import { isViewFieldDate } from '../../types/guards/isViewFieldDate';
import { isViewFieldDoubleText } from '../../types/guards/isViewFieldDoubleText';
import { isViewFieldDoubleTextChip } from '../../types/guards/isViewFieldDoubleTextChip';
import { isViewFieldNumber } from '../../types/guards/isViewFieldNumber';
import { isViewFieldPhone } from '../../types/guards/isViewFieldPhone';
import { isViewFieldRelation } from '../../types/guards/isViewFieldRelation';
import { isViewFieldText } from '../../types/guards/isViewFieldText';
import { isViewFieldURL } from '../../types/guards/isViewFieldURL';
import { GenericEditableChipCell } from '../type/components/GenericEditableChipCell';
import { GenericEditableDateCell } from '../type/components/GenericEditableDateCell';
import { GenericEditableDoubleTextCell } from '../type/components/GenericEditableDoubleTextCell';
import { GenericEditableDoubleTextChipCell } from '../type/components/GenericEditableDoubleTextChipCell';
import { GenericEditableNumberCell } from '../type/components/GenericEditableNumberCell';
import { GenericEditablePhoneCell } from '../type/components/GenericEditablePhoneCell';
import { GenericEditableRelationCell } from '../type/components/GenericEditableRelationCell';
import { GenericEditableTextCell } from '../type/components/GenericEditableTextCell';
import { GenericEditableURLCell } from '../type/components/GenericEditableURLCell';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldMetadata>;

View File

@ -1,60 +0,0 @@
import { expect } from '@storybook/jest';
import type { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { CellPositionDecorator } from '~/testing/decorators/CellPositionDecorator';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { sleep } from '~/testing/sleep';
import { EditableCellText } from '../../types/EditableCellText';
const meta: Meta<typeof EditableCellText> = {
title: 'UI/EditableCell/EditableCellText',
component: EditableCellText,
decorators: [ComponentDecorator, CellPositionDecorator],
args: {
value: 'Content',
},
};
export default meta;
type Story = StoryObj<typeof EditableCellText>;
export const DisplayMode: Story = {
render: EditableCellText,
};
export const SoftFocusMode: Story = {
...DisplayMode,
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const content = await canvas.findByText('Content');
await userEvent.click(content);
await userEvent.keyboard('{esc}');
await sleep(10);
await step('Has soft focus mode', () => {
expect(canvas.getByTestId('editable-cell-soft-focus-mode')).toBeDefined();
});
},
};
export const EditMode: Story = {
...DisplayMode,
play: async ({ canvasElement, step }) => {
const canvas = within(canvasElement);
const click = () => userEvent.click(canvas.getByText('Content'));
await step('Click once', click);
await step('Has edit mode', () => {
expect(
canvas.getByTestId('editable-cell-edit-mode-container'),
).toBeDefined();
});
},
};

View File

@ -1,7 +1,7 @@
import { useContext } from 'react';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { HotkeyScope } from '@/ui/hotkey/types/HotkeyScope';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
import { useCloseCurrentCellInEditMode } from '../../hooks/useClearCellInEditMode';
import { CellHotkeyScopeContext } from '../../states/CellHotkeyScopeContext';

View File

@ -1,5 +1,5 @@
import { useListenClickOutside } from '@/ui/hooks/useListenClickOutside';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { useListenClickOutside } from '@/ui/utilities/click-outside/hooks/useListenClickOutside';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useMoveSoftFocus } from '../../hooks/useMoveSoftFocus';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';

View File

@ -1,6 +1,6 @@
import { useRecoilCallback } from 'recoil';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { useSetSoftFocusPosition } from '../../hooks/useSetSoftFocusPosition';
import { isSoftFocusActiveState } from '../../states/isSoftFocusActiveState';

View File

@ -2,12 +2,12 @@ import { useRef } from 'react';
import styled from '@emotion/styled';
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { InplaceInputDate } from '@/ui/inplace-input/components/InplaceInputDate';
import { DateInputEdit } from '@/ui/input/date/components/DateInputEdit';
import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope';
import { useListenClickOutside } from '@/ui/utilities/click-outside/hooks/useListenClickOutside';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useListenClickOutside } from '../../../hooks/useListenClickOutside';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useEditableCell } from '../hooks/useEditableCell';
import { useEditableCell } from '../../hooks/useEditableCell';
const EditableCellDateEditModeContainer = styled.div`
margin-top: -1px;
@ -19,10 +19,7 @@ export type EditableDateProps = {
onSubmit: (date: Date) => void;
};
export function EditableCellDateEditMode({
value,
onSubmit,
}: EditableDateProps) {
export function DateCellEdit({ value, onSubmit }: EditableDateProps) {
const { closeEditableCell } = useEditableCell();
function handleDateChange(newDate: Date) {
@ -55,7 +52,7 @@ export function EditableCellDateEditMode({
return (
<EditableCellDateEditModeContainer ref={containerRef}>
<InplaceInputDate onChange={handleDateChange} value={value} />
<DateInputEdit onChange={handleDateChange} value={value} />
</EditableCellDateEditModeContainer>
);
}

View File

@ -2,13 +2,14 @@ import { ChangeEvent, useEffect, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { StyledInput } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useMoveSoftFocus } from '@/ui/table/hooks/useMoveSoftFocus';
import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useMoveSoftFocus } from '../../hooks/useMoveSoftFocus';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { useEditableCell } from '../hooks/useEditableCell';
import { useRegisterCloseCellHandlers } from '../hooks/useRegisterCloseCellHandlers';
import { useEditableCell } from '../../hooks/useEditableCell';
import { useRegisterCloseCellHandlers } from '../../hooks/useRegisterCloseCellHandlers';
import { StyledInput } from './TextCellEdit';
type OwnProps = {
firstValue: string;
@ -35,7 +36,7 @@ const StyledContainer = styled.div`
}
`;
export function EditableCellDoubleTextEditMode({
export function DoubleTextCellEdit({
firstValue,
secondValue,
firstValuePlaceholder,

View File

@ -1,6 +1,8 @@
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { ViewFieldChipMetadata, ViewFieldDefinition } from '../types/ViewField';
import {
ViewFieldChipMetadata,
ViewFieldDefinition,
} from '@/ui/table/types/ViewField';
import { GenericEditableChipCellDisplayMode } from './GenericEditableChipCellDisplayMode';
import { GenericEditableChipCellEditMode } from './GenericEditableChipCellEditMode';

View File

@ -1,7 +1,7 @@
import { useRecoilValue } from 'recoil';
import { CompanyChip } from '@/companies/components/CompanyChip';
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {

View File

@ -1,11 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldChipMetadata,
ViewFieldDefinition,
} from '@/ui/table/types/ViewField';
import { ViewFieldChipMetadata, ViewFieldDefinition } from '../types/ViewField';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldChipMetadata>;
@ -35,7 +38,7 @@ export function GenericEditableChipCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputTextCellEditMode
<TextCellEdit
placeholder={viewField.metadata.placeHolder ?? ''}
autoFocus
value={fieldValue ?? ''}

View File

@ -1,11 +1,13 @@
import { useRecoilValue } from 'recoil';
import { InplaceInputDateDisplayMode } from '@/ui/display/component/InplaceInputDateDisplayMode';
import { DateInputDisplay } from '@/ui/input/date/components/DateInputDisplay';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import { ViewFieldDateMetadata, ViewFieldDefinition } from '../types/ViewField';
import {
ViewFieldDateMetadata,
ViewFieldDefinition,
} from '@/ui/table/types/ViewField';
import { GenericEditableDateCellEditMode } from './GenericEditableDateCellEditMode';
@ -33,7 +35,7 @@ export function GenericEditableDateCell({
editModeContent={
<GenericEditableDateCellEditMode viewField={viewField} />
}
nonEditModeContent={<InplaceInputDateDisplayMode value={fieldValue} />}
nonEditModeContent={<DateInputDisplay value={fieldValue} />}
></EditableCell>
);
}

View File

@ -4,9 +4,12 @@ import { useRecoilState } from 'recoil';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDateMetadata,
ViewFieldDefinition,
} from '@/ui/table/types/ViewField';
import { EditableCellDateEditMode } from '../editable-cell/types/EditableCellDateEditMode';
import { ViewFieldDateMetadata, ViewFieldDefinition } from '../types/ViewField';
import { DateCellEdit } from './DateCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldDateMetadata>;
@ -42,7 +45,7 @@ export function GenericEditableDateCellEditMode({ viewField }: OwnProps) {
}
return (
<EditableCellDateEditMode
<DateCellEdit
value={DateTime.fromISO(fieldValue).toJSDate()}
onSubmit={handleSubmit}
/>

View File

@ -1,14 +1,13 @@
import { useRecoilValue } from 'recoil';
import { InplaceInputTextDisplayMode } from '@/ui/display/component/InplaceInputTextDisplayMode';
import { TextInputDisplay } from '@/ui/input/text/components/TextInputDisplay';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldDoubleTextMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { GenericEditableDoubleTextCellEditMode } from './GenericEditableDoubleTextCellEditMode';
@ -40,9 +39,7 @@ export function GenericEditableDoubleTextCell({ viewField }: OwnProps) {
editModeContent={
<GenericEditableDoubleTextCellEditMode viewField={viewField} />
}
nonEditModeContent={
<InplaceInputTextDisplayMode>{displayName}</InplaceInputTextDisplayMode>
}
nonEditModeContent={<TextInputDisplay>{displayName}</TextInputDisplay>}
></EditableCell>
);
}

View File

@ -1,14 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputDoubleTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputDoubleTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldDoubleTextMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { DoubleTextCellEdit } from './DoubleTextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldDoubleTextMetadata>;
@ -49,7 +49,7 @@ export function GenericEditableDoubleTextCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputDoubleTextCellEditMode
<DoubleTextCellEdit
firstValuePlaceholder={viewField.metadata.firstValuePlaceholder}
secondValuePlaceholder={viewField.metadata.secondValuePlaceholder}
firstValue={firstValue ?? ''}

View File

@ -1,10 +1,9 @@
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { TableHotkeyScope } from '../types/TableHotkeyScope';
import { TableHotkeyScope } from '@/ui/table/types/TableHotkeyScope';
import {
ViewFieldDefinition,
ViewFieldDoubleTextChipMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { GenericEditableDoubleTextChipCellDisplayMode } from './GenericEditableDoubleTextChipCellDisplayMode';
import { GenericEditableDoubleTextChipCellEditMode } from './GenericEditableDoubleTextChipCellEditMode';

View File

@ -2,7 +2,7 @@ import { useRecoilState } from 'recoil';
import { CompanyChip } from '@/companies/components/CompanyChip';
import { PersonChip } from '@/people/components/PersonChip';
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {

View File

@ -3,12 +3,12 @@ import { useRecoilState } from 'recoil';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import { EditableCellDoubleTextEditMode } from '../editable-cell/types/EditableCellDoubleTextEditMode';
import {
ViewFieldDefinition,
ViewFieldDoubleTextChipMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { DoubleTextCellEdit } from './DoubleTextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldDoubleTextChipMetadata>;
@ -61,7 +61,7 @@ export function GenericEditableDoubleTextChipCellEditMode({
}
return (
<EditableCellDoubleTextEditMode
<DoubleTextCellEdit
firstValuePlaceholder={viewField.metadata.firstValuePlaceholder}
secondValuePlaceholder={viewField.metadata.secondValuePlaceholder}
firstValue={firstValue ?? ''}

View File

@ -3,11 +3,10 @@ import { useRecoilValue } from 'recoil';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldNumberMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { GenericEditableNumberCellEditMode } from './GenericEditableNumberCellEditMode';

View File

@ -1,14 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldNumberMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldNumberMetadata>;
@ -57,10 +57,6 @@ export function GenericEditableNumberCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputTextCellEditMode
autoFocus
value={fieldValue ?? ''}
onSubmit={handleSubmit}
/>
<TextCellEdit autoFocus value={fieldValue ?? ''} onSubmit={handleSubmit} />
);
}

View File

@ -1,14 +1,13 @@
import { useRecoilValue } from 'recoil';
import { InplaceInputPhoneDisplayMode } from '@/ui/display/component/InplaceInputPhoneDisplayMode';
import { PhoneInputDisplay } from '@/ui/input/phone/components/PhoneInputDisplay';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldPhoneMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { GenericEditablePhoneCellEditMode } from './GenericEditablePhoneCellEditMode';
@ -36,7 +35,7 @@ export function GenericEditablePhoneCell({
editModeContent={
<GenericEditablePhoneCellEditMode viewField={viewField} />
}
nonEditModeContent={<InplaceInputPhoneDisplayMode value={fieldValue} />}
nonEditModeContent={<PhoneInputDisplay value={fieldValue} />}
></EditableCell>
);
}

View File

@ -1,14 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldPhoneMetadata,
} from '../types/ViewField';
} from '@/ui/table/types/ViewField';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldPhoneMetadata>;
@ -38,7 +38,7 @@ export function GenericEditablePhoneCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputTextCellEditMode
<TextCellEdit
placeholder={viewField.metadata.placeHolder ?? ''}
autoFocus
value={fieldValue ?? ''}

View File

@ -1,4 +1,4 @@
import { RelationPickerHotkeyScope } from '@/ui/relation-picker/types/RelationPickerHotkeyScope';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import {
ViewFieldDefinition,

View File

@ -1,7 +1,7 @@
import { useRecoilValue } from 'recoil';
import { CompanyChip } from '@/companies/components/CompanyChip';
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {

View File

@ -1,8 +1,8 @@
import { useRecoilState } from 'recoil';
import { CompanyPickerCell } from '@/companies/components/CompanyPickerCell';
import { EntityForSelect } from '@/ui/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
import { useEditableCell } from '@/ui/table/editable-cell/hooks/useEditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';

View File

@ -1,11 +1,13 @@
import { useRecoilValue } from 'recoil';
import { InplaceInputTextDisplayMode } from '@/ui/display/component/InplaceInputTextDisplayMode';
import { TextInputDisplay } from '@/ui/input/text/components/TextInputDisplay';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import { ViewFieldDefinition, ViewFieldTextMetadata } from '../types/ViewField';
import {
ViewFieldDefinition,
ViewFieldTextMetadata,
} from '@/ui/table/types/ViewField';
import { GenericEditableTextCellEditMode } from './GenericEditableTextCellEditMode';
@ -33,9 +35,7 @@ export function GenericEditableTextCell({
editModeContent={
<GenericEditableTextCellEditMode viewField={viewField} />
}
nonEditModeContent={
<InplaceInputTextDisplayMode>{fieldValue}</InplaceInputTextDisplayMode>
}
nonEditModeContent={<TextInputDisplay>{fieldValue}</TextInputDisplay>}
></EditableCell>
);
}

View File

@ -1,11 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldTextMetadata,
} from '@/ui/table/types/ViewField';
import { ViewFieldDefinition, ViewFieldTextMetadata } from '../types/ViewField';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldTextMetadata>;
@ -35,7 +38,7 @@ export function GenericEditableTextCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputTextCellEditMode
<TextCellEdit
placeholder={viewField.metadata.placeHolder ?? ''}
autoFocus
value={fieldValue ?? ''}

View File

@ -1,11 +1,13 @@
import { useRecoilValue } from 'recoil';
import { InplaceInputURLDisplayMode } from '@/ui/display/component/InplaceInputURLDisplayMode';
import { InplaceInputURLDisplayMode } from '@/ui/input/url/components/URLTextInputDisplay';
import { EditableCell } from '@/ui/table/editable-cell/components/EditableCell';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import { ViewFieldDefinition, ViewFieldURLMetadata } from '../types/ViewField';
import {
ViewFieldDefinition,
ViewFieldURLMetadata,
} from '@/ui/table/types/ViewField';
import { GenericEditableURLCellEditMode } from './GenericEditableURLCellEditMode';

View File

@ -1,11 +1,14 @@
import { useRecoilState } from 'recoil';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { useCurrentRowEntityId } from '@/ui/table/hooks/useCurrentEntityId';
import { useUpdateEntityField } from '@/ui/table/hooks/useUpdateEntityField';
import { tableEntityFieldFamilySelector } from '@/ui/table/states/tableEntityFieldFamilySelector';
import {
ViewFieldDefinition,
ViewFieldURLMetadata,
} from '@/ui/table/types/ViewField';
import { ViewFieldDefinition, ViewFieldURLMetadata } from '../types/ViewField';
import { TextCellEdit } from './TextCellEdit';
type OwnProps = {
viewField: ViewFieldDefinition<ViewFieldURLMetadata>;
@ -35,7 +38,7 @@ export function GenericEditableURLCellEditMode({ viewField }: OwnProps) {
}
return (
<InplaceInputTextCellEditMode
<TextCellEdit
placeholder={viewField.metadata.placeHolder ?? ''}
autoFocus
value={fieldValue ?? ''}

View File

@ -0,0 +1,59 @@
import { ChangeEvent, useEffect, useRef, useState } from 'react';
import styled from '@emotion/styled';
import { textInputStyle } from '@/ui/theme/constants/effects';
import { useRegisterCloseCellHandlers } from '../../hooks/useRegisterCloseCellHandlers';
export const StyledInput = styled.input`
margin: 0;
width: 100%;
${textInputStyle}
`;
type OwnProps = {
placeholder?: string;
autoFocus?: boolean;
value: string;
onSubmit: (newText: string) => void;
};
export function TextCellEdit({
placeholder,
autoFocus,
value,
onSubmit,
}: OwnProps) {
const [internalText, setInternalText] = useState(value);
const wrapperRef = useRef(null);
function handleSubmit() {
onSubmit(internalText);
}
function handleCancel() {
setInternalText(value);
}
function handleChange(event: ChangeEvent<HTMLInputElement>) {
setInternalText(event.target.value);
}
useEffect(() => {
setInternalText(value);
}, [value]);
useRegisterCloseCellHandlers(wrapperRef, handleSubmit, handleCancel);
return (
<StyledInput
autoComplete="off"
ref={wrapperRef}
placeholder={placeholder}
onChange={handleChange}
autoFocus={autoFocus}
value={internalText}
/>
);
}

View File

@ -1,29 +0,0 @@
import { InplaceInputDateDisplayMode } from '@/ui/display/component/InplaceInputDateDisplayMode';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { EditableCell } from '../components/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 (
<EditableCell
editModeHorizontalAlign={editModeHorizontalAlign}
editModeContent={
<EditableCellDateEditMode onSubmit={onChange} value={value} />
}
nonEditModeContent={<InplaceInputDateDisplayMode value={value} />}
editHotkeyScope={{ scope: TableHotkeyScope.CellDateEditMode }}
></EditableCell>
);
}

View File

@ -1,47 +0,0 @@
import { ReactElement } from 'react';
import { TableHotkeyScope } from '../../types/TableHotkeyScope';
import { CellSkeleton } from '../components/CellSkeleton';
import { EditableCell } from '../components/EditableCell';
import { EditableCellDoubleTextEditMode } from './EditableCellDoubleTextEditMode';
type OwnProps = {
firstValue: string;
secondValue: string;
firstValuePlaceholder: string;
secondValuePlaceholder: string;
nonEditModeContent: ReactElement;
onSubmit?: (firstValue: string, secondValue: string) => void;
onCancel?: () => void;
loading?: boolean;
};
export function EditableCellDoubleText({
firstValue,
secondValue,
firstValuePlaceholder,
secondValuePlaceholder,
onSubmit,
onCancel,
nonEditModeContent,
loading,
}: OwnProps) {
return (
<EditableCell
editHotkeyScope={{ scope: TableHotkeyScope.CellDoubleTextInput }}
editModeContent={
<EditableCellDoubleTextEditMode
firstValue={firstValue}
secondValue={secondValue}
firstValuePlaceholder={firstValuePlaceholder}
secondValuePlaceholder={secondValuePlaceholder}
onSubmit={onSubmit}
onCancel={onCancel}
/>
}
nonEditModeContent={loading ? <CellSkeleton /> : nonEditModeContent}
></EditableCell>
);
}

View File

@ -1,26 +0,0 @@
import { InplaceInputPhoneDisplayMode } from '@/ui/display/component/InplaceInputPhoneDisplayMode';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { EditableCell } from '../components/EditableCell';
type OwnProps = {
placeholder?: string;
value: string;
onSubmit?: (newText: string) => void;
};
export function EditableCellPhone({ value, placeholder, onSubmit }: OwnProps) {
return (
<EditableCell
editModeContent={
<InplaceInputTextCellEditMode
autoFocus
placeholder={placeholder || ''}
value={value}
onSubmit={(newText) => onSubmit?.(newText)}
/>
}
nonEditModeContent={<InplaceInputPhoneDisplayMode value={value} />}
/>
);
}

View File

@ -1,19 +0,0 @@
import styled from '@emotion/styled';
export const EditableCellRelationCreateButton = styled.button`
align-items: center;
background: none;
border: none;
border-radius: ${({ theme }) => theme.border.radius.sm};
cursor: pointer;
display: flex;
font-family: 'Inter';
font-size: ${({ theme }) => theme.font.size.md};
gap: ${({ theme }) => theme.spacing(2)};
height: 31px;
padding-bottom: ${({ theme }) => theme.spacing(1)};
padding-left: ${({ theme }) => theme.spacing(1)};
padding-top: ${({ theme }) => theme.spacing(1)};
user-select: none;
width: 100%;
`;

View File

@ -1,42 +0,0 @@
import { InplaceInputTextDisplayMode } from '@/ui/display/component/InplaceInputTextDisplayMode';
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { CellSkeleton } from '../components/CellSkeleton';
import { EditableCell } from '../components/EditableCell';
type OwnProps = {
placeholder?: string;
value: string;
editModeHorizontalAlign?: 'left' | 'right';
loading?: boolean;
onSubmit?: (newText: string) => void;
};
export function EditableCellText({
value,
placeholder,
editModeHorizontalAlign,
loading,
onSubmit,
}: OwnProps) {
return (
<EditableCell
editModeHorizontalAlign={editModeHorizontalAlign}
editModeContent={
<InplaceInputTextCellEditMode
placeholder={placeholder || ''}
autoFocus
value={value}
onSubmit={(newText) => onSubmit?.(newText)}
/>
}
nonEditModeContent={
loading ? (
<CellSkeleton />
) : (
<InplaceInputTextDisplayMode>{value}</InplaceInputTextDisplayMode>
)
}
></EditableCell>
);
}

View File

@ -1,46 +0,0 @@
import { InplaceInputTextCellEditMode } from '@/ui/inplace-input/components/InplaceInputTextCellEditMode';
import { RawLink } from '../../../link/components/RawLink';
import { CellSkeleton } from '../components/CellSkeleton';
import { EditableCell } from '../components/EditableCell';
type OwnProps = {
placeholder?: string;
url: string;
onChange?: (newURL: string) => void;
editModeHorizontalAlign?: 'left' | 'right';
loading?: boolean;
onSubmit?: (newURL: string) => void;
onCancel?: () => void;
};
export function EditableCellURL({
url,
placeholder,
editModeHorizontalAlign,
loading,
onSubmit,
}: OwnProps) {
return (
<EditableCell
editModeHorizontalAlign={editModeHorizontalAlign}
editModeContent={
<InplaceInputTextCellEditMode
placeholder={placeholder}
autoFocus
value={url}
onSubmit={(newURL) => onSubmit?.(newURL)}
/>
}
nonEditModeContent={
loading ? (
<CellSkeleton />
) : (
<RawLink onClick={(e) => e.stopPropagation()} href={url ?? ''}>
{url}
</RawLink>
)
}
></EditableCell>
);
}

View File

@ -1,78 +0,0 @@
import { ReactNode, useEffect, useState } from 'react';
import styled from '@emotion/styled';
import { InplaceInputTextCellEditMode } from '../../../inplace-input/components/InplaceInputTextCellEditMode';
import { EditableCell } from '../components/EditableCell';
export type EditableChipProps = {
placeholder?: string;
value: string;
editModeHorizontalAlign?: 'left' | 'right';
ChipComponent: React.ReactNode;
activityCount?: number;
onCommentClick?: (event: React.MouseEvent<HTMLDivElement>) => void;
rightEndContents?: ReactNode[];
onSubmit?: (newValue: string) => void;
onCancel?: () => void;
};
const NoEditModeContainer = styled.div`
align-items: center;
display: flex;
justify-content: space-between;
width: 100%;
`;
const RightContainer = styled.div`
margin-left: ${(props) => props.theme.spacing(1)};
`;
// TODO: move right end content in EditableCell
export function EditableCellChip({
value,
placeholder,
editModeHorizontalAlign,
ChipComponent,
rightEndContents,
onSubmit,
}: EditableChipProps) {
const [inputValue, setInputValue] = useState(value);
useEffect(() => {
setInputValue(value);
}, [value]);
const handleRightEndContentClick = (
event: React.MouseEvent<HTMLDivElement>,
) => {
event.stopPropagation();
};
return (
<EditableCell
editModeHorizontalAlign={editModeHorizontalAlign}
editModeContent={
<InplaceInputTextCellEditMode
placeholder={placeholder || ''}
autoFocus
value={inputValue}
onSubmit={(newValue) => onSubmit?.(newValue)}
/>
}
nonEditModeContent={
<NoEditModeContainer>
{ChipComponent}
<RightContainer>
{rightEndContents &&
rightEndContents.length > 0 &&
rightEndContents.map((content, index) => (
<div key={index} onClick={handleRightEndContentClick}>
{content}
</div>
))}
</RightContainer>
</NoEditModeContainer>
}
/>
);
}

View File

@ -2,7 +2,7 @@ import { useEffect } from 'react';
import { availableFiltersScopedState } from '@/ui/filter-n-sort/states/availableFiltersScopedState';
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
import { useRecoilScopedState } from '@/ui/recoil-scope/hooks/useRecoilScopedState';
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
import { TableContext } from '../states/TableContext';

View File

@ -1,7 +1,7 @@
import { useRecoilCallback } from 'recoil';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { currentHotkeyScopeState } from '@/ui/hotkey/states/internal/currentHotkeyScopeState';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { currentHotkeyScopeState } from '@/ui/utilities/hotkey/states/internal/currentHotkeyScopeState';
import { isSoftFocusActiveState } from '../states/isSoftFocusActiveState';
import { TableHotkeyScope } from '../types/TableHotkeyScope';

View File

@ -1,7 +1,7 @@
import { Key } from 'ts-key-enum';
import { useScopedHotkeys } from '@/ui/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/hotkey/hooks/useSetHotkeyScope';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope';
import { TableHotkeyScope } from '../types/TableHotkeyScope';

View File

@ -2,7 +2,6 @@ import { useRecoilCallback } from 'recoil';
import { availableFiltersScopedState } from '@/ui/filter-n-sort/states/availableFiltersScopedState';
import { FilterDefinition } from '@/ui/filter-n-sort/types/FilterDefinition';
import { useContextScopeId } from '@/ui/recoil-scope/hooks/useContextScopeId';
import { useResetTableRowSelection } from '@/ui/table/hooks/useResetTableRowSelection';
import { entityTableDimensionsState } from '@/ui/table/states/entityTableDimensionsState';
import { isFetchingEntityTableDataState } from '@/ui/table/states/isFetchingEntityTableDataState';
@ -14,6 +13,7 @@ import {
ViewFieldDefinition,
ViewFieldMetadata,
} from '@/ui/table/types/ViewField';
import { useContextScopeId } from '@/ui/utilities/recoil-scope/hooks/useContextScopeId';
export function useSetEntityTableData() {
const resetTableRowSelection = useResetTableRowSelection();

View File

@ -1,5 +1,5 @@
import { createContext } from 'react';
import { HotkeyScope } from '../../hotkey/types/HotkeyScope';
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
export const CellHotkeyScopeContext = createContext<HotkeyScope | null>(null);

View File

@ -1,71 +0,0 @@
import type { Meta, StoryObj } from '@storybook/react';
import { userEvent, within } from '@storybook/testing-library';
import { IconList } from '@/ui/icon/index';
import { RecoilScope } from '@/ui/recoil-scope/components/RecoilScope';
import { availableSorts } from '~/pages/companies/companies-sorts';
import { ComponentWithRouterDecorator } from '../../../../../../testing/decorators/ComponentWithRouterDecorator';
import { CompanyEntityTableDataMocked } from '../../../../../companies/table/components/CompanyEntityTableDataMocked';
import { TableContext } from '../../../states/TableContext';
import { TableHeader } from '../TableHeader';
const meta: Meta<typeof TableHeader> = {
title: 'UI/Table/TableHeader',
component: TableHeader,
decorators: [
(Story) => (
<RecoilScope SpecificContext={TableContext}>
<CompanyEntityTableDataMocked />
<Story />
</RecoilScope>
),
ComponentWithRouterDecorator,
],
argTypes: { viewIcon: { control: false } },
args: {
viewName: 'ViewName',
viewIcon: <IconList />,
availableSorts,
},
};
export default meta;
type Story = StoryObj<typeof TableHeader>;
export const Empty: Story = {};
export const WithSortsAndFilters: Story = {
play: async ({ canvasElement }) => {
const canvas = within(canvasElement);
const outsideClick = await canvas.findByText('ViewName');
userEvent.click(await canvas.findByText('Filter'));
userEvent.click(await canvas.findByText('Name'));
const nameInput = await canvas.findByPlaceholderText('Name');
userEvent.type(nameInput, 'My name');
userEvent.click(outsideClick);
userEvent.click(await canvas.findByText('Sort'));
userEvent.click(await canvas.findByText('Name'));
userEvent.click(await canvas.findByText('Sort'));
userEvent.click(await canvas.findByText('Creation'));
userEvent.click(await canvas.findByText('Sort'));
userEvent.click(await canvas.findByText('Address'));
userEvent.click(await canvas.findByText('Filter'));
userEvent.click(await canvas.findByText('Employees'));
const employeesInput = await canvas.findByPlaceholderText('Employees');
userEvent.type(employeesInput, '12');
userEvent.click(await canvas.findByText('Sort'));
userEvent.click(await canvas.findByText('Url'));
userEvent.click(await canvas.findByText('Filter'));
userEvent.click(await canvas.findByText('Created at'));
userEvent.click(await canvas.findByText('6'));
userEvent.click(outsideClick);
},
};

View File

@ -1,5 +1,5 @@
import { EntityForSelect } from '@/ui/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/relation-picker/types/EntityTypeForSelect';
import { EntityForSelect } from '@/ui/input/relation-picker/types/EntityForSelect';
import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
export type ViewFieldType =
| 'text'