mirror of
https://github.com/rowyio/rowy.git
synced 2025-12-29 00:16:39 +01:00
improve Table code organization & fix memo issues
This commit is contained in:
@@ -29,7 +29,7 @@ import SettingsIcon from "@mui/icons-material/SettingsOutlined";
|
||||
import EvalIcon from "@mui/icons-material/PlayCircleOutline";
|
||||
|
||||
import MenuContents, { IMenuContentsProps } from "./MenuContents";
|
||||
import ColumnHeader from "@src/components/Table/Column";
|
||||
import ColumnHeader from "@src/components/Table/Mock/Column";
|
||||
|
||||
import {
|
||||
projectScope,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useAtom } from "jotai";
|
||||
import { useLocation, useParams, Link as RouterLink } from "react-router-dom";
|
||||
import { useParams, Link as RouterLink } from "react-router-dom";
|
||||
import { find, camelCase, uniq } from "lodash-es";
|
||||
|
||||
import {
|
||||
@@ -1,5 +1,10 @@
|
||||
import { forwardRef, useRef } from "react";
|
||||
import { memo, useRef } from "react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import type { Header } from "@tanstack/react-table";
|
||||
import type {
|
||||
DraggableProvided,
|
||||
DraggableStateSnapshot,
|
||||
} from "react-beautiful-dnd";
|
||||
|
||||
import {
|
||||
styled,
|
||||
@@ -7,8 +12,8 @@ import {
|
||||
TooltipProps,
|
||||
tooltipClasses,
|
||||
Fade,
|
||||
Grid,
|
||||
GridProps,
|
||||
Stack,
|
||||
StackProps,
|
||||
IconButton,
|
||||
Typography,
|
||||
} from "@mui/material";
|
||||
@@ -16,21 +21,58 @@ import DropdownIcon from "@mui/icons-material/MoreHoriz";
|
||||
import LockIcon from "@mui/icons-material/LockOutlined";
|
||||
|
||||
import ColumnHeaderSort, { SORT_STATES } from "./ColumnHeaderSort";
|
||||
import ColumnHeaderDragHandle from "./ColumnHeaderDragHandle";
|
||||
import ColumnHeaderResizer from "./ColumnHeaderResizer";
|
||||
|
||||
import { projectScope, altPressAtom } from "@src/atoms/projectScope";
|
||||
import {
|
||||
tableScope,
|
||||
selectedCellAtom,
|
||||
columnMenuAtom,
|
||||
tableSortsAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import { getFieldProp } from "@src/components/fields";
|
||||
import { COLUMN_HEADER_HEIGHT } from "@src/components/Table/Column";
|
||||
import { ColumnConfig } from "@src/types/table";
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
import { spreadSx } from "@src/utils/ui";
|
||||
import { COLUMN_HEADER_HEIGHT } from "@src/components/Table/Mock/Column";
|
||||
import type { ColumnConfig } from "@src/types/table";
|
||||
import type { TableRow } from "@src/types/table";
|
||||
|
||||
export { COLUMN_HEADER_HEIGHT };
|
||||
|
||||
const StyledColumnHeader = styled(Stack)(({ theme }) => ({
|
||||
position: "relative",
|
||||
height: "100%",
|
||||
border: `1px solid ${theme.palette.divider}`,
|
||||
"& + &": { borderLeftStyle: "none" },
|
||||
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
padding: theme.spacing(0, 0.5, 0, 1),
|
||||
"& svg, & button": { display: "block", zIndex: 1 },
|
||||
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.secondary,
|
||||
transition: theme.transitions.create("color", {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
"&:hover": { color: theme.palette.text.primary },
|
||||
|
||||
"& .MuiIconButton-root": {
|
||||
color: theme.palette.text.disabled,
|
||||
transition: theme.transitions.create(
|
||||
["background-color", "opacity", "color"],
|
||||
{ duration: theme.transitions.duration.short }
|
||||
),
|
||||
},
|
||||
[`&:hover .MuiIconButton-root,
|
||||
&:focus .MuiIconButton-root,
|
||||
&:focus-within .MuiIconButton-root,
|
||||
.MuiIconButton-root:focus`]: {
|
||||
color: theme.palette.text.primary,
|
||||
opacity: 1,
|
||||
},
|
||||
}));
|
||||
|
||||
const LightTooltip = styled(({ className, ...props }: TooltipProps) => (
|
||||
<Tooltip {...props} classes={{ popper: className }} />
|
||||
))(({ theme }) => ({
|
||||
@@ -44,18 +86,34 @@ const LightTooltip = styled(({ className, ...props }: TooltipProps) => (
|
||||
},
|
||||
}));
|
||||
|
||||
export interface IColumnHeaderProps extends Partial<GridProps> {
|
||||
export interface IColumnHeaderProps
|
||||
extends Partial<Omit<StackProps, "style" | "sx">> {
|
||||
header: Header<TableRow, any>;
|
||||
column: ColumnConfig;
|
||||
|
||||
provided: DraggableProvided;
|
||||
snapshot: DraggableStateSnapshot;
|
||||
|
||||
width: number;
|
||||
isSelectedCell: boolean;
|
||||
focusInsideCell: boolean;
|
||||
children: React.ReactNode;
|
||||
canEditColumns: boolean;
|
||||
isLastFrozen: boolean;
|
||||
}
|
||||
|
||||
export const ColumnHeader = forwardRef(function ColumnHeader(
|
||||
{ column, width, focusInsideCell, children, ...props }: IColumnHeaderProps,
|
||||
ref: React.Ref<HTMLDivElement>
|
||||
) {
|
||||
export const ColumnHeader = memo(function ColumnHeader({
|
||||
header,
|
||||
column,
|
||||
provided,
|
||||
snapshot,
|
||||
width,
|
||||
isSelectedCell,
|
||||
focusInsideCell,
|
||||
canEditColumns,
|
||||
isLastFrozen,
|
||||
}: IColumnHeaderProps) {
|
||||
const openColumnMenu = useSetAtom(columnMenuAtom, tableScope);
|
||||
const setSelectedCell = useSetAtom(selectedCellAtom, tableScope);
|
||||
const [altPress] = useAtom(altPressAtom, projectScope);
|
||||
const [tableSorts] = useAtom(tableSortsAtom, tableScope);
|
||||
|
||||
@@ -74,11 +132,19 @@ export const ColumnHeader = forwardRef(function ColumnHeader(
|
||||
: tableSorts[0]?.direction || "none";
|
||||
|
||||
return (
|
||||
<Grid
|
||||
<StyledColumnHeader
|
||||
role="columnheader"
|
||||
id={`column-header-${column.key}`}
|
||||
ref={ref}
|
||||
{...props}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
data-row-id={"_rowy_header"}
|
||||
data-col-id={header.id}
|
||||
data-frozen={header.column.getIsPinned() || undefined}
|
||||
data-frozen-last={isLastFrozen || undefined}
|
||||
tabIndex={isSelectedCell ? 0 : -1}
|
||||
aria-colindex={header.index + 1}
|
||||
aria-readonly={!canEditColumns}
|
||||
aria-selected={isSelectedCell}
|
||||
aria-sort={
|
||||
currentSort === "none"
|
||||
? "none"
|
||||
@@ -86,34 +152,40 @@ export const ColumnHeader = forwardRef(function ColumnHeader(
|
||||
? "ascending"
|
||||
: "descending"
|
||||
}
|
||||
container
|
||||
alignItems="center"
|
||||
wrap="nowrap"
|
||||
style={{
|
||||
left: header.column.getIsPinned()
|
||||
? header.column.getStart()
|
||||
: undefined,
|
||||
zIndex: header.column.getIsPinned() ? 11 : 10,
|
||||
...provided.draggableProps.style,
|
||||
width,
|
||||
borderLeftStyle: snapshot.isDragging ? "solid" : undefined,
|
||||
}}
|
||||
onContextMenu={handleOpenMenu}
|
||||
sx={[
|
||||
{
|
||||
height: "100%",
|
||||
"& svg, & button": { display: "block", zIndex: 1 },
|
||||
border: (theme) => `1px solid ${theme.palette.divider}`,
|
||||
|
||||
backgroundColor: "background.default",
|
||||
color: "text.secondary",
|
||||
transition: (theme) =>
|
||||
theme.transitions.create("color", {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
"&:hover": { color: "text.primary" },
|
||||
|
||||
position: "relative",
|
||||
|
||||
py: 0,
|
||||
pr: 0.5,
|
||||
pl: 1,
|
||||
width: "100%",
|
||||
},
|
||||
...spreadSx(props.sx),
|
||||
]}
|
||||
onClick={(e) => {
|
||||
setSelectedCell({
|
||||
path: "_rowy_header",
|
||||
columnKey: header.id,
|
||||
focusInside: false,
|
||||
});
|
||||
(e.target as HTMLDivElement).focus();
|
||||
}}
|
||||
onDoubleClick={(e) => {
|
||||
setSelectedCell({
|
||||
path: "_rowy_header",
|
||||
columnKey: header.id,
|
||||
focusInside: true,
|
||||
});
|
||||
(e.target as HTMLDivElement).focus();
|
||||
}}
|
||||
>
|
||||
{provided.dragHandleProps && (
|
||||
<ColumnHeaderDragHandle
|
||||
dragHandleProps={provided.dragHandleProps}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
/>
|
||||
)}
|
||||
|
||||
{width > 140 && (
|
||||
<Tooltip
|
||||
title={
|
||||
@@ -127,8 +199,7 @@ export const ColumnHeader = forwardRef(function ColumnHeader(
|
||||
placement="bottom-start"
|
||||
arrow
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
<div
|
||||
onClick={() => {
|
||||
navigator.clipboard.writeText(column.key);
|
||||
}}
|
||||
@@ -139,96 +210,87 @@ export const ColumnHeader = forwardRef(function ColumnHeader(
|
||||
) : (
|
||||
getFieldProp("icon", (column as any).type)
|
||||
)}
|
||||
</Grid>
|
||||
</div>
|
||||
</Tooltip>
|
||||
)}
|
||||
|
||||
<Grid
|
||||
item
|
||||
xs
|
||||
sx={{ flexShrink: 1, overflow: "hidden", my: 0, ml: 0.5, mr: -30 / 8 }}
|
||||
>
|
||||
<LightTooltip
|
||||
title={
|
||||
<Typography
|
||||
sx={{
|
||||
typography: "caption",
|
||||
fontWeight: "fontWeightMedium",
|
||||
lineHeight: `${COLUMN_HEADER_HEIGHT - 2 - 4}px`,
|
||||
textOverflow: "clip",
|
||||
}}
|
||||
color="inherit"
|
||||
>
|
||||
{column.name as string}
|
||||
</Typography>
|
||||
}
|
||||
enterDelay={1000}
|
||||
placement="bottom-start"
|
||||
disableInteractive
|
||||
TransitionComponent={Fade}
|
||||
sx={{ "& .MuiTooltip-tooltip": { marginTop: "-28px !important" } }}
|
||||
>
|
||||
<LightTooltip
|
||||
title={
|
||||
<Typography
|
||||
noWrap
|
||||
sx={{
|
||||
typography: "caption",
|
||||
fontWeight: "fontWeightMedium",
|
||||
lineHeight: `${COLUMN_HEADER_HEIGHT - 2 - 4}px`,
|
||||
textOverflow: "clip",
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
}}
|
||||
component="div"
|
||||
color="inherit"
|
||||
>
|
||||
{altPress ? (
|
||||
<>
|
||||
{column.index} <code>{column.fieldName}</code>
|
||||
</>
|
||||
) : (
|
||||
column.name
|
||||
)}
|
||||
{column.name as string}
|
||||
</Typography>
|
||||
</LightTooltip>
|
||||
</Grid>
|
||||
}
|
||||
enterDelay={1000}
|
||||
placement="bottom-start"
|
||||
disableInteractive
|
||||
TransitionComponent={Fade}
|
||||
sx={{ "& .MuiTooltip-tooltip": { marginTop: "-28px !important" } }}
|
||||
>
|
||||
<Typography
|
||||
noWrap
|
||||
sx={{
|
||||
typography: "caption",
|
||||
fontWeight: "fontWeightMedium",
|
||||
textOverflow: "clip",
|
||||
position: "relative",
|
||||
zIndex: 1,
|
||||
|
||||
flexGrow: 1,
|
||||
flexShrink: 1,
|
||||
overflow: "hidden",
|
||||
my: 0,
|
||||
ml: 0.5,
|
||||
mr: -30 / 8,
|
||||
}}
|
||||
component="div"
|
||||
color="inherit"
|
||||
>
|
||||
{altPress ? (
|
||||
<>
|
||||
{column.index} <code>{column.fieldName}</code>
|
||||
</>
|
||||
) : (
|
||||
column.name
|
||||
)}
|
||||
</Typography>
|
||||
</LightTooltip>
|
||||
|
||||
{column.type !== FieldType.id && (
|
||||
<Grid item>
|
||||
<ColumnHeaderSort
|
||||
sortKey={sortKey}
|
||||
currentSort={currentSort}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
/>
|
||||
</Grid>
|
||||
<ColumnHeaderSort
|
||||
sortKey={sortKey}
|
||||
currentSort={currentSort}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Grid item>
|
||||
<Tooltip title="Column settings">
|
||||
<IconButton
|
||||
size="small"
|
||||
aria-label={`Column settings for ${column.name as string}`}
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
id={`column-settings-${column.key}`}
|
||||
color="inherit"
|
||||
onClick={handleOpenMenu}
|
||||
ref={buttonRef}
|
||||
sx={{
|
||||
transition: (theme) =>
|
||||
theme.transitions.create("color", {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
<Tooltip title="Column settings">
|
||||
<IconButton
|
||||
size="small"
|
||||
tabIndex={focusInsideCell ? 0 : -1}
|
||||
id={`column-settings-${column.key}`}
|
||||
onClick={handleOpenMenu}
|
||||
ref={buttonRef}
|
||||
>
|
||||
<DropdownIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
||||
color: "text.disabled",
|
||||
"[role='columnheader']:hover &, [role='columnheader']:focus &, [role='columnheader']:focus-within &, &:focus":
|
||||
{ color: "text.primary" },
|
||||
}}
|
||||
>
|
||||
<DropdownIcon />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
</Grid>
|
||||
|
||||
{children}
|
||||
</Grid>
|
||||
{header.column.getCanResize() && (
|
||||
<ColumnHeaderResizer
|
||||
isResizing={header.column.getIsResizing()}
|
||||
onMouseDown={header.getResizeHandler()}
|
||||
onTouchStart={header.getResizeHandler()}
|
||||
/>
|
||||
)}
|
||||
</StyledColumnHeader>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
58
src/components/Table/ColumnHeader/ColumnHeaderDragHandle.tsx
Normal file
58
src/components/Table/ColumnHeader/ColumnHeaderDragHandle.tsx
Normal file
@@ -0,0 +1,58 @@
|
||||
import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
|
||||
import { DragVertical } from "@src/assets/icons";
|
||||
|
||||
export interface IColumnHeaderDragHandleProps {
|
||||
dragHandleProps: DraggableProvidedDragHandleProps;
|
||||
tabIndex: number;
|
||||
}
|
||||
|
||||
export default function ColumnHeaderDragHandle({
|
||||
dragHandleProps,
|
||||
tabIndex,
|
||||
}: IColumnHeaderDragHandleProps) {
|
||||
return (
|
||||
<div
|
||||
{...dragHandleProps}
|
||||
tabIndex={tabIndex}
|
||||
aria-describedby={
|
||||
tabIndex > -1 ? dragHandleProps["aria-describedby"] : undefined
|
||||
}
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
zIndex: 0,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
outline: "none",
|
||||
}}
|
||||
className="column-drag-handle"
|
||||
>
|
||||
<DragVertical
|
||||
sx={{
|
||||
opacity: 0,
|
||||
borderRadius: 2,
|
||||
transition: (theme) => theme.transitions.create(["opacity"]),
|
||||
"[role='columnheader']:hover &, [role='columnheader']:focus-within &":
|
||||
{
|
||||
opacity: 0.5,
|
||||
},
|
||||
".column-drag-handle:hover &": {
|
||||
opacity: 1,
|
||||
},
|
||||
".column-drag-handle:active &": {
|
||||
opacity: 1,
|
||||
color: "primary.main",
|
||||
},
|
||||
".column-drag-handle:focus &": {
|
||||
opacity: 1,
|
||||
color: "primary.main",
|
||||
outline: "2px solid",
|
||||
outlineColor: "primary.main",
|
||||
},
|
||||
}}
|
||||
style={{ width: 8 }}
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
import { styled } from "@mui/material";
|
||||
|
||||
export interface IStyledResizerProps {
|
||||
export interface IColumnHeaderResizerProps {
|
||||
isResizing: boolean;
|
||||
}
|
||||
|
||||
export const StyledResizer = styled("div", {
|
||||
name: "StyledResizer",
|
||||
export const ColumnHeaderResizer = styled("div", {
|
||||
name: "ColumnHeaderResizer",
|
||||
shouldForwardProp: (prop) => prop !== "isResizing",
|
||||
})<IStyledResizerProps>(({ theme, isResizing }) => ({
|
||||
})<IColumnHeaderResizerProps>(({ theme, isResizing }) => ({
|
||||
position: "absolute",
|
||||
zIndex: 5,
|
||||
right: 0,
|
||||
@@ -51,6 +51,6 @@ export const StyledResizer = styled("div", {
|
||||
transform: isResizing ? "scaleY(1.5) !important" : undefined,
|
||||
},
|
||||
}));
|
||||
StyledResizer.displayName = "StyledResizer";
|
||||
ColumnHeaderResizer.displayName = "ColumnHeaderResizer";
|
||||
|
||||
export default StyledResizer;
|
||||
export default ColumnHeaderResizer;
|
||||
@@ -1,3 +1,4 @@
|
||||
import { memo } from "react";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { colord } from "colord";
|
||||
|
||||
@@ -17,7 +18,7 @@ export interface IColumnHeaderSortProps {
|
||||
tabIndex?: number;
|
||||
}
|
||||
|
||||
export default function ColumnHeaderSort({
|
||||
export const ColumnHeaderSort = memo(function ColumnHeaderSort({
|
||||
sortKey,
|
||||
currentSort,
|
||||
tabIndex,
|
||||
@@ -34,7 +35,7 @@ export default function ColumnHeaderSort({
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
title={nextSort === "none" ? "Unsort" : `Sort by ${nextSort}ending`}
|
||||
title={nextSort === "none" ? "Remove sort" : `Sort by ${nextSort}ending`}
|
||||
>
|
||||
<IconButton
|
||||
disableFocusRipple={true}
|
||||
@@ -68,13 +69,6 @@ export default function ColumnHeaderSort({
|
||||
|
||||
position: "relative",
|
||||
opacity: currentSort !== "none" ? 1 : 0,
|
||||
"[role='columnheader']:hover &, [role='columnheader']:focus &, [role='columnheader']:focus-within &, &:focus":
|
||||
{ opacity: 1 },
|
||||
|
||||
transition: (theme) =>
|
||||
theme.transitions.create(["background-color", "opacity"], {
|
||||
duration: theme.transitions.duration.short,
|
||||
}),
|
||||
|
||||
"& .arrow": {
|
||||
transition: (theme) =>
|
||||
@@ -108,4 +102,6 @@ export default function ColumnHeaderSort({
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default ColumnHeaderSort;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { memo } from "react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import type { ITableCellProps } from "@src/components/Table/withTableCell";
|
||||
import type { IRenderedTableCellProps } from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Stack, Tooltip, IconButton, alpha } from "@mui/material";
|
||||
import { CopyCells as CopyCellsIcon } from "@src/assets/icons";
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
export const FinalColumn = memo(function FinalColumn({
|
||||
row,
|
||||
focusInsideCell,
|
||||
}: ITableCellProps) {
|
||||
}: IRenderedTableCellProps) {
|
||||
const [userRoles] = useAtom(userRolesAtom, projectScope);
|
||||
const [addRowIdType] = useAtom(tableAddRowIdTypeAtom, projectScope);
|
||||
const confirm = useSetAtom(confirmDialogAtom, projectScope);
|
||||
|
||||
@@ -105,7 +105,6 @@ export const Column = forwardRef(function Column(
|
||||
|
||||
ml: 0.5,
|
||||
}}
|
||||
aria-hidden
|
||||
>
|
||||
{label}
|
||||
</Typography>
|
||||
@@ -221,6 +221,7 @@ export default function Table({
|
||||
canAddColumns={canAddColumns}
|
||||
canEditColumns={canEditColumns}
|
||||
lastFrozen={lastFrozen}
|
||||
columnSizing={columnSizing}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -233,6 +234,7 @@ export default function Table({
|
||||
rows={rows}
|
||||
canEditCells={canEditCells}
|
||||
lastFrozen={lastFrozen}
|
||||
columnSizing={columnSizing}
|
||||
/>
|
||||
)}
|
||||
</StyledTable>
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { memo } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import type { Column, Row } from "@tanstack/react-table";
|
||||
import type { Column, Row, ColumnSizingState } from "@tanstack/react-table";
|
||||
|
||||
import StyledRow from "./Styled/StyledRow";
|
||||
import OutOfOrderIndicator from "./OutOfOrderIndicator";
|
||||
import CellValidation from "./CellValidation";
|
||||
import CellValidation from "./TableCell";
|
||||
import { RowsSkeleton } from "./TableSkeleton";
|
||||
|
||||
import {
|
||||
@@ -29,9 +30,12 @@ export interface ITableBodyProps {
|
||||
|
||||
canEditCells: boolean;
|
||||
lastFrozen?: string;
|
||||
|
||||
/** Re-render when local column sizing changes */
|
||||
columnSizing: ColumnSizingState;
|
||||
}
|
||||
|
||||
export default function TableBody({
|
||||
export const TableBody = memo(function TableBody({
|
||||
containerRef,
|
||||
leafColumns,
|
||||
rows,
|
||||
@@ -105,9 +109,11 @@ export default function TableBody({
|
||||
: undefined
|
||||
}
|
||||
isSelectedCell={isSelectedCell}
|
||||
focusInsideCell={isSelectedCell && selectedCell?.focusInside}
|
||||
isReadOnlyCell={isReadOnlyCell}
|
||||
canEditCells={canEditCells}
|
||||
lastFrozen={lastFrozen}
|
||||
isLastFrozen={lastFrozen === cell.column.id}
|
||||
width={cell.column.getSize()}
|
||||
rowHeight={tableSchema.rowHeight || DEFAULT_ROW_HEIGHT}
|
||||
/>
|
||||
);
|
||||
@@ -127,4 +133,6 @@ export default function TableBody({
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default TableBody;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { memo } from "react";
|
||||
import { useAtom, useSetAtom } from "jotai";
|
||||
import { useSetAtom } from "jotai";
|
||||
import { ErrorBoundary } from "react-error-boundary";
|
||||
import { flexRender } from "@tanstack/react-table";
|
||||
import type { Row, Cell } from "@tanstack/react-table";
|
||||
@@ -8,7 +8,7 @@ import { styled } from "@mui/material/styles";
|
||||
import ErrorIcon from "@mui/icons-material/ErrorOutline";
|
||||
import WarningIcon from "@mui/icons-material/WarningAmber";
|
||||
|
||||
import StyledCell from "./Styled/StyledCell";
|
||||
import StyledCell from "@src/components/Table/Styled/StyledCell";
|
||||
import { InlineErrorFallback } from "@src/components/ErrorFallback";
|
||||
import RichTooltip from "@src/components/RichTooltip";
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
contextMenuTargetAtom,
|
||||
} from "@src/atoms/tableScope";
|
||||
import type { TableRow } from "@src/types/table";
|
||||
import type { ITableCellProps } from "./withTableCell";
|
||||
import type { IRenderedTableCellProps } from "./withRenderTableCell";
|
||||
|
||||
const Dot = styled("div")(({ theme }) => ({
|
||||
position: "absolute",
|
||||
@@ -39,31 +39,34 @@ const Dot = styled("div")(({ theme }) => ({
|
||||
},
|
||||
}));
|
||||
|
||||
export interface ICellValidationProps {
|
||||
export interface ITableCellProps {
|
||||
row: Row<TableRow>;
|
||||
cell: Cell<TableRow, any>;
|
||||
index: number;
|
||||
isSelectedCell: boolean;
|
||||
focusInsideCell: boolean;
|
||||
isReadOnlyCell: boolean;
|
||||
canEditCells: boolean;
|
||||
rowHeight: number;
|
||||
lastFrozen?: string;
|
||||
isLastFrozen: boolean;
|
||||
width: number;
|
||||
left?: number;
|
||||
}
|
||||
|
||||
export const CellValidation = memo(function MemoizedCellValidation({
|
||||
export const TableCell = memo(function TableCell({
|
||||
row,
|
||||
cell,
|
||||
index,
|
||||
isSelectedCell,
|
||||
focusInsideCell,
|
||||
isReadOnlyCell,
|
||||
canEditCells,
|
||||
rowHeight,
|
||||
lastFrozen,
|
||||
isLastFrozen,
|
||||
width,
|
||||
left,
|
||||
}: ICellValidationProps) {
|
||||
const [selectedCell, setSelectedCell] = useAtom(selectedCellAtom, tableScope);
|
||||
const focusInsideCell = selectedCell?.focusInside ?? false;
|
||||
}: ITableCellProps) {
|
||||
const setSelectedCell = useSetAtom(selectedCellAtom, tableScope);
|
||||
const setContextMenuTarget = useSetAtom(contextMenuTargetAtom, tableScope);
|
||||
|
||||
const value = cell.getValue();
|
||||
@@ -97,10 +100,10 @@ export const CellValidation = memo(function MemoizedCellValidation({
|
||||
);
|
||||
}
|
||||
|
||||
const tableCellComponentProps: ITableCellProps = {
|
||||
const tableCellComponentProps: IRenderedTableCellProps = {
|
||||
...cell.getContext(),
|
||||
value,
|
||||
focusInsideCell: isSelectedCell && focusInsideCell,
|
||||
focusInsideCell,
|
||||
setFocusInsideCell: (focusInside: boolean) =>
|
||||
setSelectedCell({
|
||||
path: row.original._rowy_ref.path,
|
||||
@@ -117,7 +120,7 @@ export const CellValidation = memo(function MemoizedCellValidation({
|
||||
data-row-id={row.id}
|
||||
data-col-id={cell.column.id}
|
||||
data-frozen={cell.column.getIsPinned() || undefined}
|
||||
data-frozen-last={lastFrozen === cell.column.id || undefined}
|
||||
data-frozen-last={isLastFrozen || undefined}
|
||||
role="gridcell"
|
||||
tabIndex={isSelectedCell && !focusInsideCell ? 0 : -1}
|
||||
aria-colindex={index + 1}
|
||||
@@ -133,7 +136,7 @@ export const CellValidation = memo(function MemoizedCellValidation({
|
||||
}
|
||||
aria-invalid={isInvalid || isMissing}
|
||||
style={{
|
||||
width: cell.column.getSize(),
|
||||
width,
|
||||
height: rowHeight,
|
||||
left,
|
||||
backgroundColor:
|
||||
@@ -178,4 +181,4 @@ export const CellValidation = memo(function MemoizedCellValidation({
|
||||
);
|
||||
});
|
||||
|
||||
export default CellValidation;
|
||||
export default TableCell;
|
||||
2
src/components/Table/TableCell/index.ts
Normal file
2
src/components/Table/TableCell/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { default } from "./TableCell";
|
||||
export * from "./TableCell";
|
||||
@@ -32,7 +32,7 @@ export interface ICellOptions {
|
||||
popoverProps?: Partial<PopoverProps>;
|
||||
}
|
||||
|
||||
export interface ITableCellProps<TValue = any>
|
||||
export interface IRenderedTableCellProps<TValue = any>
|
||||
extends CellContext<TableRow, TValue> {
|
||||
value: TValue;
|
||||
focusInsideCell: boolean;
|
||||
@@ -60,7 +60,7 @@ export default function withTableCell(
|
||||
options: ICellOptions = {}
|
||||
) {
|
||||
return memo(
|
||||
function TableCell({
|
||||
function RenderedTableCell({
|
||||
row,
|
||||
column,
|
||||
value,
|
||||
@@ -68,7 +68,7 @@ export default function withTableCell(
|
||||
setFocusInsideCell,
|
||||
disabled,
|
||||
rowHeight,
|
||||
}: ITableCellProps) {
|
||||
}: IRenderedTableCellProps) {
|
||||
// Render inline editor cell after timeout on mount
|
||||
// to improve scroll performance
|
||||
const [inlineEditorReady, setInlineEditorReady] = useState(false);
|
||||
@@ -2,14 +2,12 @@ import { memo } from "react";
|
||||
import { useAtom } from "jotai";
|
||||
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
|
||||
import type { DropResult } from "react-beautiful-dnd";
|
||||
import type { HeaderGroup } from "@tanstack/react-table";
|
||||
import type { ColumnSizingState, HeaderGroup } from "@tanstack/react-table";
|
||||
import type { TableRow } from "@src/types/table";
|
||||
|
||||
import StyledRow from "./Styled/StyledRow";
|
||||
import ColumnHeader from "./ColumnHeader";
|
||||
import StyledResizer from "./Styled/StyledResizer";
|
||||
import FinalColumnHeader from "./FinalColumn/FinalColumnHeader";
|
||||
import { DragVertical } from "@src/assets/icons";
|
||||
|
||||
import { tableScope, selectedCellAtom } from "@src/atoms/tableScope";
|
||||
import { DEFAULT_ROW_HEIGHT } from "@src/components/Table";
|
||||
@@ -20,6 +18,9 @@ export interface ITableHeaderProps {
|
||||
canAddColumns: boolean;
|
||||
canEditColumns: boolean;
|
||||
lastFrozen?: string;
|
||||
|
||||
/** Re-render when local column sizing changes */
|
||||
columnSizing: ColumnSizingState;
|
||||
}
|
||||
|
||||
export const TableHeader = memo(function TableHeader({
|
||||
@@ -29,8 +30,8 @@ export const TableHeader = memo(function TableHeader({
|
||||
canEditColumns,
|
||||
lastFrozen,
|
||||
}: ITableHeaderProps) {
|
||||
const [selectedCell, setSelectedCell] = useAtom(selectedCellAtom, tableScope);
|
||||
const focusInsideCell = selectedCell?.focusInside ?? false;
|
||||
const [selectedCell] = useAtom(selectedCellAtom, tableScope);
|
||||
const focusInside = selectedCell?.focusInside ?? false;
|
||||
|
||||
return (
|
||||
<DragDropContext onDragEnd={handleDropColumn}>
|
||||
@@ -58,7 +59,7 @@ export const TableHeader = memo(function TableHeader({
|
||||
data-row-id={"_rowy_header"}
|
||||
data-col-id={header.id}
|
||||
tabIndex={isSelectedCell ? 0 : -1}
|
||||
focusInsideCell={isSelectedCell && focusInsideCell}
|
||||
focusInsideCell={isSelectedCell && focusInside}
|
||||
aria-colindex={header.index + 1}
|
||||
aria-readonly={!canEditColumns}
|
||||
aria-selected={isSelectedCell}
|
||||
@@ -78,105 +79,16 @@ export const TableHeader = memo(function TableHeader({
|
||||
>
|
||||
{(provided, snapshot) => (
|
||||
<ColumnHeader
|
||||
key={header.id}
|
||||
data-row-id={"_rowy_header"}
|
||||
data-col-id={header.id}
|
||||
data-frozen={header.column.getIsPinned() || undefined}
|
||||
data-frozen-last={lastFrozen === header.id || undefined}
|
||||
ref={provided.innerRef}
|
||||
{...provided.draggableProps}
|
||||
tabIndex={isSelectedCell ? 0 : -1}
|
||||
aria-colindex={header.index + 1}
|
||||
aria-readonly={!canEditColumns}
|
||||
aria-selected={isSelectedCell}
|
||||
header={header}
|
||||
column={header.column.columnDef.meta!}
|
||||
style={{
|
||||
width: header.getSize(),
|
||||
left: header.column.getIsPinned()
|
||||
? header.column.getStart()
|
||||
: undefined,
|
||||
...provided.draggableProps.style,
|
||||
zIndex: header.column.getIsPinned() ? 11 : 10,
|
||||
}}
|
||||
provided={provided}
|
||||
snapshot={snapshot}
|
||||
width={header.getSize()}
|
||||
sx={
|
||||
snapshot.isDragging
|
||||
? undefined
|
||||
: { "& + &": { borderLeft: "none" } }
|
||||
}
|
||||
onClick={(e) => {
|
||||
setSelectedCell({
|
||||
path: "_rowy_header",
|
||||
columnKey: header.id,
|
||||
focusInside: false,
|
||||
});
|
||||
(e.target as HTMLDivElement).focus();
|
||||
}}
|
||||
onDoubleClick={(e) => {
|
||||
setSelectedCell({
|
||||
path: "_rowy_header",
|
||||
columnKey: header.id,
|
||||
focusInside: true,
|
||||
});
|
||||
(e.target as HTMLDivElement).focus();
|
||||
}}
|
||||
focusInsideCell={isSelectedCell && focusInsideCell}
|
||||
>
|
||||
<div
|
||||
{...provided.dragHandleProps}
|
||||
tabIndex={isSelectedCell && focusInsideCell ? 0 : -1}
|
||||
aria-describedby={
|
||||
isSelectedCell && focusInsideCell
|
||||
? provided.dragHandleProps?.["aria-describedby"]
|
||||
: undefined
|
||||
}
|
||||
style={{
|
||||
position: "absolute",
|
||||
inset: 0,
|
||||
zIndex: 0,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
outline: "none",
|
||||
}}
|
||||
className="column-drag-handle"
|
||||
>
|
||||
<DragVertical
|
||||
sx={{
|
||||
opacity: 0,
|
||||
borderRadius: 2,
|
||||
transition: (theme) =>
|
||||
theme.transitions.create(["opacity"]),
|
||||
"[role='columnheader']:hover &, [role='columnheader']:focus-within &":
|
||||
{
|
||||
opacity: 0.5,
|
||||
},
|
||||
".column-drag-handle:hover &": {
|
||||
opacity: 1,
|
||||
},
|
||||
".column-drag-handle:active &": {
|
||||
opacity: 1,
|
||||
color: "primary.main",
|
||||
},
|
||||
".column-drag-handle:focus &": {
|
||||
opacity: 1,
|
||||
color: "primary.main",
|
||||
outline: "2px solid",
|
||||
outlineColor: "primary.main",
|
||||
},
|
||||
}}
|
||||
style={{ width: 8 }}
|
||||
preserveAspectRatio="xMidYMid slice"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{header.column.getCanResize() && (
|
||||
<StyledResizer
|
||||
isResizing={header.column.getIsResizing()}
|
||||
onMouseDown={header.getResizeHandler()}
|
||||
onTouchStart={header.getResizeHandler()}
|
||||
/>
|
||||
)}
|
||||
</ColumnHeader>
|
||||
isSelectedCell={isSelectedCell}
|
||||
focusInsideCell={isSelectedCell && focusInside}
|
||||
canEditColumns={canEditColumns}
|
||||
isLastFrozen={lastFrozen === header.id}
|
||||
/>
|
||||
)}
|
||||
</Draggable>
|
||||
);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { colord } from "colord";
|
||||
|
||||
import { Fade, Stack, Skeleton, Button } from "@mui/material";
|
||||
import { AddColumn as AddColumnIcon } from "@src/assets/icons";
|
||||
import Column from "./Column";
|
||||
import Column from "./Mock/Column";
|
||||
|
||||
import { projectScope, userSettingsAtom } from "@src/atoms/projectScope";
|
||||
import {
|
||||
|
||||
@@ -22,7 +22,9 @@ import { TableColumn as TableColumnIcon } from "@src/assets/icons";
|
||||
import { IStepProps } from ".";
|
||||
import { AirtableConfig } from "@src/components/TableModals/ImportAirtableWizard";
|
||||
import FadeList from "@src/components/TableModals/ScrollableList";
|
||||
import Column, { COLUMN_HEADER_HEIGHT } from "@src/components/Table/Column";
|
||||
import Column, {
|
||||
COLUMN_HEADER_HEIGHT,
|
||||
} from "@src/components/Table/Mock/Column";
|
||||
import ColumnSelect from "@src/components/Table/ColumnSelect";
|
||||
|
||||
import {
|
||||
|
||||
@@ -6,8 +6,8 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import ScrollableList from "@src/components/TableModals/ScrollableList";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
import FieldsDropdown from "@src/components/ColumnModals/FieldsDropdown";
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
import { SELECTABLE_TYPES } from "@src/components/TableModals/ImportExistingWizard/utils";
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useAtom } from "jotai";
|
||||
import { find } from "lodash-es";
|
||||
|
||||
import { styled, Grid } from "@mui/material";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import { tableScope, tableSchemaAtom } from "@src/atoms/tableScope";
|
||||
|
||||
@@ -26,7 +26,9 @@ import { TableColumn as TableColumnIcon } from "@src/assets/icons";
|
||||
import { IStepProps } from ".";
|
||||
import { CsvConfig } from "@src/components/TableModals/ImportCsvWizard";
|
||||
import FadeList from "@src/components/TableModals/ScrollableList";
|
||||
import Column, { COLUMN_HEADER_HEIGHT } from "@src/components/Table/Column";
|
||||
import Column, {
|
||||
COLUMN_HEADER_HEIGHT,
|
||||
} from "@src/components/Table/Mock/Column";
|
||||
import ColumnSelect from "@src/components/Table/ColumnSelect";
|
||||
|
||||
import {
|
||||
|
||||
@@ -7,8 +7,8 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import ScrollableList from "@src/components/TableModals/ScrollableList";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
import FieldsDropdown from "@src/components/ColumnModals/FieldsDropdown";
|
||||
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
|
||||
@@ -3,8 +3,8 @@ import { find } from "lodash-es";
|
||||
import { parseJSON } from "date-fns";
|
||||
|
||||
import { styled, Grid } from "@mui/material";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import { tableScope, tableSchemaAtom } from "@src/atoms/tableScope";
|
||||
|
||||
@@ -20,7 +20,7 @@ import DragHandleIcon from "@mui/icons-material/DragHandle";
|
||||
import { AddColumn as AddColumnIcon } from "@src/assets/icons";
|
||||
|
||||
import ScrollableList from "@src/components/TableModals/ScrollableList";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import EmptyState from "@src/components/EmptyState";
|
||||
|
||||
import { tableScope, tableRowsAtom } from "@src/atoms/tableScope";
|
||||
|
||||
@@ -14,7 +14,9 @@ import DoneIcon from "@mui/icons-material/Done";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import ScrollableList from "@src/components/TableModals/ScrollableList";
|
||||
import Column, { COLUMN_HEADER_HEIGHT } from "@src/components/Table/Column";
|
||||
import Column, {
|
||||
COLUMN_HEADER_HEIGHT,
|
||||
} from "@src/components/Table/Mock/Column";
|
||||
|
||||
export default function Step2Rename({
|
||||
config,
|
||||
|
||||
@@ -6,8 +6,8 @@ import ChevronRightIcon from "@mui/icons-material/ChevronRight";
|
||||
|
||||
import { IStepProps } from ".";
|
||||
import ScrollableList from "@src/components/TableModals/ScrollableList";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
import FieldsDropdown from "@src/components/ColumnModals/FieldsDropdown";
|
||||
|
||||
import { tableScope, tableRowsAtom } from "@src/atoms/tableScope";
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useAtom } from "jotai";
|
||||
import { IStepProps } from ".";
|
||||
|
||||
import { styled, Grid } from "@mui/material";
|
||||
import Column from "@src/components/Table/Column";
|
||||
import Cell from "@src/components/Table/Cell";
|
||||
import Column from "@src/components/Table/Mock/Column";
|
||||
import Cell from "@src/components/Table/Mock/Cell";
|
||||
|
||||
import { tableScope, tableRowsAtom } from "@src/atoms/tableScope";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import ActionIcon from "@mui/icons-material/TouchAppOutlined";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ActionIcon />,
|
||||
description:
|
||||
"Button with pre-defined action script or triggers a Cloud Function. Optionally supports Undo and Redo.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "inline", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "inline", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import CheckboxIcon from "@mui/icons-material/ToggleOnOutlined";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <CheckboxIcon />,
|
||||
description: "True/false value. Default: false.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "inline", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "inline", {
|
||||
usesRowData: true,
|
||||
}),
|
||||
csvImportParser: (value: string) => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import CodeIcon from "@mui/icons-material/Code";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <CodeIcon />,
|
||||
description: "Raw code edited with the Monaco Editor.",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
popoverProps: {
|
||||
anchorOrigin: { vertical: "top", horizontal: "center" },
|
||||
PaperProps: { sx: { borderRadius: 1 } },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
import { toColor } from "react-color-palette";
|
||||
|
||||
import ColorIcon from "@mui/icons-material/Colorize";
|
||||
@@ -25,7 +25,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ColorIcon />,
|
||||
description:
|
||||
"Color stored as Hex, RGB, and HSV. Edited with a visual picker.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IDisplayCellProps } from "@src/components/fields/types";
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
import { get } from "lodash-es";
|
||||
|
||||
export default function ConnectService({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import ConnectServiceIcon from "@mui/icons-material/Http";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -28,7 +28,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ConnectServiceIcon />,
|
||||
description:
|
||||
"Connects to an external web service to fetch a list of results.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
transparentPopover: true,
|
||||
}),
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IDisplayCellProps } from "@src/components/fields/types";
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
|
||||
export default function ConnectTable({
|
||||
value,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { ConnectTable as ConnectTableIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -28,7 +28,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ConnectTableIcon />,
|
||||
description:
|
||||
"Connects to an existing table to fetch a snapshot of values from a row. Requires Rowy Run and Algolia setup.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
transparentPopover: true,
|
||||
}),
|
||||
|
||||
@@ -3,7 +3,7 @@ import { IDisplayCellProps } from "@src/components/fields/types";
|
||||
import { ButtonBase, Grid, Chip } from "@mui/material";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
import { get } from "lodash-es";
|
||||
import { getLabel } from "./utils";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import ConnectorIcon from "@mui/icons-material/Cable";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -29,7 +29,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ConnectorIcon />,
|
||||
description:
|
||||
"Connects to any table or API to fetch a list of results based on a text query or row data.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { CreatedAt as CreatedAtIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: null,
|
||||
icon: <CreatedAtIcon />,
|
||||
description: "Displays the timestamp of when the row was created. Read-only.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { CreatedBy as CreatedByIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -25,7 +25,7 @@ export const config: IFieldConfig = {
|
||||
icon: <CreatedByIcon />,
|
||||
description:
|
||||
"Displays the user that created the row and timestamp. Read-only.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
import { parse, format } from "date-fns";
|
||||
import { DATE_FORMAT } from "@src/constants/dates";
|
||||
|
||||
@@ -28,7 +28,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <DateIcon />,
|
||||
description: `Formatted date. Format is configurable, default: ${DATE_FORMAT}. Edited with a visual picker.`,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "focus", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "focus", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
import { parseJSON, format } from "date-fns";
|
||||
import { DATE_TIME_FORMAT } from "@src/constants/dates";
|
||||
|
||||
@@ -36,7 +36,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <DateTimeIcon />,
|
||||
description: `Formatted date & time. Format is configurable, default: ${DATE_TIME_FORMAT}. Edited with a visual picker.`,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "focus", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "focus", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Derivative as DerivativeIcon } from "@src/assets/icons";
|
||||
import Settings, { settingsValidator } from "./Settings";
|
||||
@@ -15,7 +15,7 @@ export const config: IFieldConfig = {
|
||||
icon: <DerivativeIcon />,
|
||||
description:
|
||||
"Value derived from the rest of the row’s values. Displayed using any other field type. Requires Rowy Run set up.",
|
||||
TableCell: withTableCell(() => null, null),
|
||||
TableCell: withRenderTableCell(() => null, null),
|
||||
SideDrawerField: () => null as any,
|
||||
contextMenuActions: ContextMenuActions,
|
||||
settings: Settings,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import DurationIcon from "@mui/icons-material/TimerOutlined";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -20,7 +20,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: {},
|
||||
icon: <DurationIcon />,
|
||||
description: "Duration calculated from two timestamps.",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
popoverProps: { PaperProps: { sx: { p: 1 } } },
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function Email(props: IEditorCellProps<string>) {
|
||||
return <EditorCellTextField {...props} InputProps={{ type: "email" }} />;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import EmailIcon from "@mui/icons-material/MailOutlined";
|
||||
import DisplayCell from "@src/components/fields/ShortText/DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
icon: <EmailIcon />,
|
||||
description: "Email address. Not validated.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
filter: {
|
||||
operators: filterOperators,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IDisplayCellProps } from "@src/components/fields/types";
|
||||
|
||||
import { Grid, Chip } from "@mui/material";
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
|
||||
import { FileIcon } from ".";
|
||||
import { FileValue } from "@src/types/table";
|
||||
|
||||
@@ -8,7 +8,7 @@ import { format } from "date-fns";
|
||||
|
||||
import { alpha, Stack, Grid, Tooltip, Chip, IconButton } from "@mui/material";
|
||||
import { Upload as UploadIcon } from "@src/assets/icons";
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
import CircularProgressOptical from "@src/components/CircularProgressOptical";
|
||||
|
||||
import { projectScope, confirmDialogAtom } from "@src/atoms/projectScope";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import FileIcon from "@mui/icons-material/AttachFile";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -22,7 +22,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: [],
|
||||
icon: <FileIcon />,
|
||||
description: "File uploaded to Firebase Storage. Supports any file type.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "inline", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "inline", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { lazy } from "react";
|
||||
import { GeoPoint } from "firebase/firestore";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import GeoPointIcon from "@mui/icons-material/PinDropOutlined";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -21,7 +21,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: {},
|
||||
icon: <GeoPointIcon />,
|
||||
description: "Geo point is represented as latitude/longitude pair.",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
popoverProps: { PaperProps: { sx: { p: 1, pt: 0 } } },
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import DisplayCell from "./DisplayCell";
|
||||
import { Id as IdIcon } from "@src/assets/icons";
|
||||
@@ -17,7 +17,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: "",
|
||||
icon: <IdIcon />,
|
||||
description: "Displays the row’s ID. Read-only. Cannot be sorted.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Image as ImageIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ImageIcon />,
|
||||
description:
|
||||
"Image file uploaded to Firebase Storage. Supports JPEG, PNG, SVG, GIF, WebP, AVIF, JPEG XL.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "inline", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "inline", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Json as JsonIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <JsonIcon />,
|
||||
description: "Object edited with a visual JSON editor.",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
popoverProps: { PaperProps: { sx: { p: 1 } } },
|
||||
}),
|
||||
csvImportParser: (value) => {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function LongText(props: IEditorCellProps<string>) {
|
||||
return <EditorCellTextField {...props} InputProps={{ multiline: true }} />;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import LongTextIcon from "@mui/icons-material/Notes";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -29,7 +29,7 @@ export const config: IFieldConfig = {
|
||||
icon: <LongTextIcon />,
|
||||
description: "Text displayed on multiple lines.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
filter: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Markdown as MarkdownIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -21,7 +21,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <MarkdownIcon />,
|
||||
description: "Markdown editor with preview",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover"),
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover"),
|
||||
SideDrawerField,
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -5,7 +5,7 @@ import WarningIcon from "@mui/icons-material/WarningAmber";
|
||||
import { ChevronDown } from "@src/assets/icons";
|
||||
|
||||
import { sanitiseValue } from "./utils";
|
||||
import ChipList from "@src/components/Table/ChipList";
|
||||
import ChipList from "@src/components/Table/TableCell/ChipList";
|
||||
import FormattedChip from "@src/components/FormattedChip";
|
||||
|
||||
export default function MultiSelect({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { MultiSelect as MultiSelectIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -32,7 +32,7 @@ export const config: IFieldConfig = {
|
||||
icon: <MultiSelectIcon />,
|
||||
description:
|
||||
"Multiple values from predefined options. Options are searchable and users can optionally input custom values.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
transparentPopover: false,
|
||||
}),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function Number_(props: IEditorCellProps<number>) {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Number as NumberIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -22,7 +22,7 @@ export const config: IFieldConfig = {
|
||||
icon: <NumberIcon />,
|
||||
description: "Numeric value.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
filter: {
|
||||
operators: filterOperators,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function Percentage(props: IEditorCellProps<number>) {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Percentage as PercentageIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -30,7 +30,7 @@ export const config: IFieldConfig = {
|
||||
requireConfiguration: true,
|
||||
description: "Percentage stored as a number between 0 and 1.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
filter: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function Phone(props: IEditorCellProps<string>) {
|
||||
return <EditorCellTextField {...props} InputProps={{ type: "tel" }} />;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import PhoneIcon from "@mui/icons-material/PhoneOutlined";
|
||||
import DisplayCell from "@src/components/fields/ShortText/DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
icon: <PhoneIcon />,
|
||||
description: "Phone number stored as text. Not validated.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
filter: {
|
||||
operators: filterOperators,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import RatingIcon from "@mui/icons-material/StarBorder";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -26,7 +26,7 @@ export const config: IFieldConfig = {
|
||||
requireConfiguration: true,
|
||||
description:
|
||||
"Rating displayed as stars. Max stars is configurable, default: 5 stars.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "inline"),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "inline"),
|
||||
settings: Settings,
|
||||
SideDrawerField,
|
||||
filter: {
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useAtom } from "jotai";
|
||||
import { doc, deleteField } from "firebase/firestore";
|
||||
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
import { InputAdornment, Tooltip } from "@mui/material";
|
||||
import ErrorIcon from "@mui/icons-material/ErrorOutline";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Reference } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <Reference />,
|
||||
description: "Firestore document reference",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "focus", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "focus", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import RichTextIcon from "@mui/icons-material/TextFormat";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
icon: <RichTextIcon />,
|
||||
description: "HTML edited with a rich text editor.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover"),
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover"),
|
||||
SideDrawerField,
|
||||
};
|
||||
export default config;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function ShortText(props: IEditorCellProps<string>) {
|
||||
return <EditorCellTextField {...props} />;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import ShortTextIcon from "@mui/icons-material/ShortText";
|
||||
import DisplayCell from "@src/components/fields/ShortText/DisplayCell";
|
||||
@@ -30,7 +30,7 @@ export const config: IFieldConfig = {
|
||||
icon: <ShortTextIcon />,
|
||||
description: "Text displayed on a single line.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell),
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
filter: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { SingleSelect as SingleSelectIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -27,7 +27,7 @@ export const config: IFieldConfig = {
|
||||
icon: <SingleSelectIcon />,
|
||||
description:
|
||||
"Single value from predefined options. Options are searchable and users can optionally input custom values.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
transparentPopover: true,
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Slider as SliderIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
icon: <SliderIcon />,
|
||||
requireConfiguration: true,
|
||||
description: "Numeric value edited with a Slider. Range is configurable.",
|
||||
TableCell: withTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, SideDrawerField, "popover", {
|
||||
popoverProps: { PaperProps: { sx: { p: 1, pt: 5 } } },
|
||||
}),
|
||||
settings: Settings,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { Status as StatusIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
initializable: true,
|
||||
icon: <StatusIcon />,
|
||||
description: "Displays field value as custom status text.",
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "popover", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "popover", {
|
||||
disablePadding: true,
|
||||
transparentPopover: true,
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { SubTable as SubTableIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
|
||||
settings: Settings,
|
||||
description:
|
||||
"Connects to a sub-table in the current row. Also displays number of rows inside the sub-table. Max sub-table depth: 100.",
|
||||
TableCell: withTableCell(DisplayCell, null, "focus", {
|
||||
TableCell: withRenderTableCell(DisplayCell, null, "focus", {
|
||||
usesRowData: true,
|
||||
disablePadding: true,
|
||||
}),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { UpdatedAt as UpdatedAtIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -25,7 +25,7 @@ export const config: IFieldConfig = {
|
||||
icon: <UpdatedAtIcon />,
|
||||
description:
|
||||
"Displays the timestamp of the last update to the row. Read-only.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import { UpdatedBy as UpdatedByIcon } from "@src/assets/icons";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -26,7 +26,7 @@ export const config: IFieldConfig = {
|
||||
icon: <UpdatedByIcon />,
|
||||
description:
|
||||
"Displays the user that last updated the row, timestamp, and updated field key. Read-only.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IEditorCellProps } from "@src/components/fields/types";
|
||||
import EditorCellTextField from "@src/components/Table/EditorCellTextField";
|
||||
import EditorCellTextField from "@src/components/Table/TableCell/EditorCellTextField";
|
||||
|
||||
export default function Url(props: IEditorCellProps<string>) {
|
||||
return <EditorCellTextField {...props} InputProps={{ type: "url" }} />;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import UrlIcon from "@mui/icons-material/Link";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
icon: <UrlIcon />,
|
||||
description: "Web address. Not validated.",
|
||||
contextMenuActions: BasicContextMenuActions,
|
||||
TableCell: withTableCell(DisplayCell, EditorCell, "focus", {
|
||||
TableCell: withRenderTableCell(DisplayCell, EditorCell, "focus", {
|
||||
disablePadding: true,
|
||||
}),
|
||||
SideDrawerField,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { lazy } from "react";
|
||||
import { IFieldConfig, FieldType } from "@src/components/fields/types";
|
||||
import withTableCell from "@src/components/Table/withTableCell";
|
||||
import withRenderTableCell from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
|
||||
import UserIcon from "@mui/icons-material/PersonOutlined";
|
||||
import DisplayCell from "./DisplayCell";
|
||||
@@ -23,7 +23,7 @@ export const config: IFieldConfig = {
|
||||
initialValue: null,
|
||||
icon: <UserIcon />,
|
||||
description: "User information and optionally, timestamp. Read-only.",
|
||||
TableCell: withTableCell(DisplayCell, null),
|
||||
TableCell: withRenderTableCell(DisplayCell, null),
|
||||
SideDrawerField,
|
||||
settings: Settings,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FieldType } from "@src/constants/fields";
|
||||
import type { ITableCellProps } from "@src/components/Table/withTableCell";
|
||||
import type { IRenderedTableCellProps } from "@src/components/Table/TableCell/withRenderTableCell";
|
||||
import type { PopoverProps } from "@mui/material";
|
||||
import type {
|
||||
ColumnConfig,
|
||||
@@ -27,7 +27,7 @@ export interface IFieldConfig {
|
||||
selectedCell: SelectedCell,
|
||||
reset: () => void
|
||||
) => IContextMenuItem[];
|
||||
TableCell: React.ComponentType<ITableCellProps>;
|
||||
TableCell: React.ComponentType<IRenderedTableCellProps>;
|
||||
SideDrawerField: React.ComponentType<ISideDrawerFieldProps>;
|
||||
settings?: React.ComponentType<ISettingsProps>;
|
||||
settingsValidator?: (config: Record<string, any>) => Record<string, string>;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import Logo from "@src/assets/Logo";
|
||||
import BreadcrumbsTableRoot from "@src/components/Table/BreadcrumbsTableRoot";
|
||||
import BreadcrumbsTableRoot from "@src/components/Table/Breadcrumbs/BreadcrumbsTableRoot";
|
||||
import { FadeProps, Typography } from "@mui/material";
|
||||
|
||||
export enum ROUTES {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { useLocation, useNavigate, useParams } from "react-router-dom";
|
||||
import { find, isEqual } from "lodash-es";
|
||||
|
||||
import Modal from "@src/components/Modal";
|
||||
import BreadcrumbsSubTable from "@src/components/Table/BreadcrumbsSubTable";
|
||||
import BreadcrumbsSubTable from "@src/components/Table/Breadcrumbs/BreadcrumbsSubTable";
|
||||
import ErrorFallback from "@src/components/ErrorFallback";
|
||||
import TableSourceFirestore from "@src/sources/TableSourceFirestore";
|
||||
import TableToolbarSkeleton from "@src/components/TableToolbar/TableToolbarSkeleton";
|
||||
|
||||
Reference in New Issue
Block a user