Merge branch 'anishroy' of https://github.com/iamanishroy/rowy into develop

This commit is contained in:
shamsmosowi
2022-11-26 00:15:37 +11:00
2 changed files with 256 additions and 2 deletions

View File

@@ -0,0 +1,252 @@
import {
useEffect,
useRef,
useMemo,
useState,
ChangeEvent,
forwardRef,
} from "react";
import { useAtom, useSetAtom } from "jotai";
import { isEqual } from "lodash-es";
import { colord } from "colord";
import {
DragDropContext,
Droppable,
Draggable,
DropResult,
} from "react-beautiful-dnd";
import { Box, AutocompleteProps, Theme } from "@mui/material";
import VisibilityIcon from "@mui/icons-material/VisibilityOutlined";
// import VisibilityOffIcon from "@mui/icons-material/VisibilityOffOutlined";
import ViewColumnOutlinedIcon from "@mui/icons-material/ViewColumnOutlined";
import IconSlash from "@src/components/IconSlash";
import DragIndicatorOutlinedIcon from "@mui/icons-material/DragIndicatorOutlined";
import ColumnSelect, { ColumnItem } from "@src/components/Table/ColumnSelect";
import ButtonWithStatus from "@src/components/ButtonWithStatus";
import {
globalScope,
userSettingsAtom,
updateUserSettingsAtom,
} from "@src/atoms/globalScope";
import {
tableScope,
tableIdAtom,
updateColumnAtom,
} from "@src/atoms/tableScope";
import { formatSubTableName } from "@src/utils/table";
export default function ManageColumns() {
const buttonRef = useRef<HTMLButtonElement>(null);
const [userSettings] = useAtom(userSettingsAtom, globalScope);
const [tableId] = useAtom(tableIdAtom, tableScope);
const [open, setOpen] = useState(false);
// Store local selection here
// Initialize hiddenFields from user doc
const userDocHiddenFields = useMemo(
() =>
userSettings.tables?.[formatSubTableName(tableId)]?.hiddenFields ?? [],
[userSettings.tables, tableId]
);
const [hiddenFields, setHiddenFields] =
useState<string[]>(userDocHiddenFields);
useEffect(() => {
setHiddenFields(userDocHiddenFields);
}, [userDocHiddenFields]);
// const tableColumns = tableColumnsOrdered.map(({ key, name }) => ({
// value: key,
// label: name,
// }));
// Save when MultiSelect closes
const [updateUserSettings] = useAtom(updateUserSettingsAtom, globalScope);
const handleSave = () => {
// Only update if there were any changes because its slow to update
if (!isEqual(hiddenFields, userDocHiddenFields) && updateUserSettings) {
updateUserSettings({
tables: { [formatSubTableName(tableId)]: { hiddenFields } },
});
}
setOpen(false);
};
// disable drag if search box is not empty
const [disableDrag, setDisableDrag] = useState<boolean>(false);
const renderOption: AutocompleteProps<
any,
true,
false,
any
>["renderOption"] = (props, option, { selected }) => {
const slashColor = (theme: Theme) =>
colord(theme.palette.background.paper)
.mix("#fff", theme.palette.mode === "dark" ? 0.16 : 0)
.alpha(1);
return (
<Draggable
draggableId={option.value}
index={option.index}
isDragDisabled={disableDrag}
>
{(provided) => (
<li {...props} ref={provided.innerRef} {...provided.draggableProps}>
<Box
sx={[{ position: "relative", height: "1.5rem" }]}
{...provided.dragHandleProps}
>
<DragIndicatorOutlinedIcon
color="disabled"
sx={[{ marginRight: "6px", opacity: disableDrag ? 0.6 : 1 }]}
/>
</Box>
<ColumnItem option={option}>
<Box
sx={[
{ position: "relative", height: "1.5rem" },
selected
? { color: "primary.main" }
: {
opacity: 0,
".MuiAutocomplete-option.Mui-focused &": {
opacity: 0.5,
},
},
]}
>
<VisibilityIcon />
<IconSlash
sx={[
{
"& .icon-slash-mask": {
stroke: (theme) => slashColor(theme).toHslString(),
},
".Mui-focused & .icon-slash-mask": {
stroke: (theme) =>
slashColor(theme)
.mix(
theme.palette.primary.main,
theme.palette.action.selectedOpacity +
theme.palette.action.hoverOpacity
)
.alpha(1)
.toHslString(),
},
},
selected ? { strokeDashoffset: 0 } : {},
]}
/>
</Box>
</ColumnItem>
</li>
)}
</Draggable>
);
};
const updateColumn = useSetAtom(updateColumnAtom, tableScope);
function handleOnDragEnd(result: DropResult) {
if (!result.destination) return;
updateColumn({
key: result.draggableId,
config: {},
index: result.destination.index,
});
}
function checkToDisableDrag(e: ChangeEvent<HTMLInputElement>) {
setDisableDrag(e.target.value !== "");
}
const ListboxComponent = forwardRef(function ListboxComponent(
props: React.HTMLAttributes<HTMLElement>,
ulRef: any /*React.ForwardedRef<HTMLUListElement>*/
) {
const { children, ...other } = props;
return (
<DragDropContext onDragEnd={handleOnDragEnd}>
<Droppable droppableId="columns_manager" direction="vertical">
{(provided) => (
<ul
{...other}
{...provided.droppableProps}
ref={(ref) => {
provided.innerRef(ref);
if (ulRef !== null) {
ulRef(ref);
}
}}
>
{props.children}
{provided.placeholder}
</ul>
)}
</Droppable>
</DragDropContext>
);
});
return (
<>
<ButtonWithStatus
startIcon={<ViewColumnOutlinedIcon />}
onClick={() => setOpen((o) => !o)}
active={hiddenFields.length > 0}
ref={buttonRef}
>
{"Columns"}
</ButtonWithStatus>
<ColumnSelect
TextFieldProps={{
style: { display: "none" },
onInput: checkToDisableDrag,
SelectProps: {
open,
MenuProps: {
anchorEl: buttonRef.current,
anchorOrigin: { vertical: "bottom", horizontal: "left" },
transformOrigin: { vertical: "top", horizontal: "left" },
sx: {
"& .MuiAutocomplete-listbox .MuiAutocomplete-option[aria-selected=true]":
{
backgroundColor: "transparent",
},
},
},
},
}}
{...{
AutocompleteProps: {
renderOption,
ListboxComponent,
// ListboxProps: {
// ...provided.droppableProps,
// ref: provided.innerRef,
// },
},
}}
label="Hidden fields"
labelPlural="fields"
value={hiddenFields ?? []}
onChange={(updates: string[]) => {
setHiddenFields(updates);
setDisableDrag(false);
}}
onClose={handleSave}
clearText="Show all"
selectAllText="Hide all"
doneText="Apply"
/>
</>
);
}

View File

@@ -14,7 +14,8 @@ import { ButtonSkeleton } from "./TableToolbarSkeleton";
import AddRow from "./AddRow";
import LoadedRowsStatus from "./LoadedRowsStatus";
import TableSettings from "./TableSettings";
import HiddenFields from "./HiddenFields";
// import HiddenFields from "./HiddenFields";
import ManageColumns from "./ManageColumns";
import RowHeight from "./RowHeight";
import TableInformation from "./TableInformation";
@@ -89,7 +90,8 @@ export default function TableToolbar() {
>
<AddRow />
<div /> {/* Spacer */}
<HiddenFields />
{/* <HiddenFields /> */}
<ManageColumns />
<Suspense fallback={<ButtonSkeleton />}>
<Filters />
</Suspense>