mirror of
https://github.com/cloudreve/frontend.git
synced 2025-12-25 19:52:48 +00:00
feat: unify list reordering, fix DnD cross-group bug, and use existing icons
This commit is contained in:
parent
bd712f506f
commit
db13c312ab
|
|
@ -11,8 +11,7 @@ import {
|
|||
} from "../../../Common/StyledComponents.tsx";
|
||||
import Add from "../../../Icons/Add.tsx";
|
||||
import Dismiss from "../../../Icons/Dismiss.tsx";
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import ArrowDown from "../../../Icons/ArrowDown.tsx";
|
||||
import { DndProvider, useDrag, useDrop } from "react-dnd";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
|
||||
|
|
@ -140,10 +139,21 @@ function DraggableEmojiRow({
|
|||
<Dismiss fontSize={"small"} />
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => moveRow(i, i - 1)} disabled={isFirst}>
|
||||
<KeyboardArrowUpIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
transform: "rotate(180deg)",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => moveRow(i, i + 1)} disabled={isLast}>
|
||||
<KeyboardArrowDownIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</NoWrapCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
|
|
@ -38,8 +38,7 @@ import Dismiss from "../../../../Icons/Dismiss.tsx";
|
|||
import SettingForm from "../../../../Pages/Setting/SettingForm.tsx";
|
||||
import MagicVarDialog, { MagicVar } from "../../../Common/MagicVarDialog.tsx";
|
||||
import { NoMarginHelperText } from "../../Settings.tsx";
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import ArrowDown from "../../../../Icons/ArrowDown.tsx";
|
||||
import { DndProvider, useDrag, useDrop } from "react-dnd";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import { SelectChangeEvent } from "@mui/material";
|
||||
|
|
@ -112,21 +111,21 @@ function DraggableTemplateRow({ i, moveRow, onExtChange, onNameChange, onDelete,
|
|||
accept: DND_TYPE,
|
||||
hover(item: any, monitor) {
|
||||
if (!ref.current) return;
|
||||
|
||||
|
||||
const dragIndex = item.index;
|
||||
const hoverIndex = i;
|
||||
if (dragIndex === hoverIndex) return;
|
||||
|
||||
|
||||
const hoverBoundingRect = ref.current.getBoundingClientRect();
|
||||
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
|
||||
const clientOffset = monitor.getClientOffset();
|
||||
if (!clientOffset) return;
|
||||
|
||||
|
||||
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
|
||||
|
||||
|
||||
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) return;
|
||||
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) return;
|
||||
|
||||
|
||||
moveRow(dragIndex, hoverIndex);
|
||||
item.index = hoverIndex;
|
||||
},
|
||||
|
|
@ -171,10 +170,21 @@ function DraggableTemplateRow({ i, moveRow, onExtChange, onNameChange, onDelete,
|
|||
<Dismiss fontSize={"small"} />
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => moveRow(i, i - 1)} disabled={isFirst}>
|
||||
<KeyboardArrowUpIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
transform: "rotate(180deg)",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => moveRow(i, i + 1)} disabled={isLast}>
|
||||
<KeyboardArrowDownIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</NoWrapTableCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ interface ViewerGroupProps {
|
|||
index: number;
|
||||
onDelete: (e: React.MouseEvent<HTMLElement>) => void;
|
||||
onGroupChange: (g: ViewerGroup) => void;
|
||||
dndType: string;
|
||||
}
|
||||
|
||||
const DND_TYPE = "viewer-row";
|
||||
|
|
@ -49,10 +50,11 @@ const DraggableViewerRow = memo(function DraggableViewerRow({
|
|||
onMoveDown,
|
||||
isLast,
|
||||
isFirst,
|
||||
dndType,
|
||||
}: any) {
|
||||
const ref = React.useRef<HTMLTableRowElement>(null);
|
||||
const [, drop] = useDrop({
|
||||
accept: DND_TYPE,
|
||||
accept: dndType,
|
||||
hover(item: any, monitor) {
|
||||
if (!ref.current) return;
|
||||
|
||||
|
|
@ -75,7 +77,7 @@ const DraggableViewerRow = memo(function DraggableViewerRow({
|
|||
},
|
||||
});
|
||||
const [{ isDragging }, drag] = useDrag({
|
||||
type: DND_TYPE,
|
||||
type: dndType,
|
||||
item: { index },
|
||||
collect: (monitor) => ({
|
||||
isDragging: monitor.isDragging(),
|
||||
|
|
@ -97,7 +99,7 @@ const DraggableViewerRow = memo(function DraggableViewerRow({
|
|||
);
|
||||
});
|
||||
|
||||
const ViewerGroupRow = memo(({ group, index, onDelete, onGroupChange }: ViewerGroupProps) => {
|
||||
const ViewerGroupRow = memo(({ group, index, onDelete, onGroupChange, dndType }: ViewerGroupProps) => {
|
||||
const { t } = useTranslation("dashboard");
|
||||
|
||||
const onViewerChange = useMemo(() => {
|
||||
|
|
@ -195,6 +197,7 @@ const ViewerGroupRow = memo(({ group, index, onDelete, onGroupChange }: ViewerGr
|
|||
onMoveDown={() => handleMoveDown(idx)}
|
||||
isFirst={idx === 0}
|
||||
isLast={idx === viewers.length - 1}
|
||||
dndType={dndType}
|
||||
/>
|
||||
))}
|
||||
</TableBody>
|
||||
|
|
@ -289,6 +292,7 @@ const FileViewerList = memo(({ config, onChange }: FileViewerListProps) => {
|
|||
key={index}
|
||||
onDelete={onGroupDelete[index]}
|
||||
onGroupChange={onGroupChange[index]}
|
||||
dndType={`viewer-row-${index}`}
|
||||
/>
|
||||
))}
|
||||
<SecondaryButton variant={"contained"} {...bindTrigger(addNewPopupState)} startIcon={<Add />} sx={{ mt: 1 }}>
|
||||
|
|
|
|||
|
|
@ -8,8 +8,7 @@ import { ViewerIcon } from "../../../../FileManager/Dialogs/OpenWith.tsx";
|
|||
import Dismiss from "../../../../Icons/Dismiss.tsx";
|
||||
import Edit from "../../../../Icons/Edit.tsx";
|
||||
import FileViewerEditDialog from "./FileViewerEditDialog.tsx";
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import ArrowDown from "../../../../Icons/ArrowDown.tsx";
|
||||
|
||||
export interface FileViewerRowProps {
|
||||
viewer: Viewer;
|
||||
|
|
@ -103,10 +102,21 @@ const FileViewerRow = React.memo(
|
|||
</NoWrapCell>
|
||||
<NoWrapCell>
|
||||
<IconButton size="small" onClick={onMoveUp} disabled={isFirst}>
|
||||
<KeyboardArrowUpIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
transform: "rotate(180deg)",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={onMoveDown} disabled={isLast}>
|
||||
<KeyboardArrowDownIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
</NoWrapCell>
|
||||
</TableRow>
|
||||
|
|
|
|||
|
|
@ -23,8 +23,7 @@ import Dismiss from "../../../Icons/Dismiss.tsx";
|
|||
import { FileManagerIndex } from "../../FileManager.tsx";
|
||||
import AddColumn from "./AddColumn.tsx";
|
||||
import { getColumnTypeDefaults, ListViewColumnSetting } from "./Column.tsx";
|
||||
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
|
||||
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
|
||||
import ArrowDown from "../../../Icons/ArrowDown.tsx";
|
||||
import { DndProvider, useDrag, useDrop } from "react-dnd";
|
||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||
import React from "react";
|
||||
|
|
@ -50,21 +49,21 @@ const DraggableColumnRow: React.FC<DraggableColumnRowProps> = ({ column, index,
|
|||
accept: DND_TYPE,
|
||||
hover(item: any, monitor) {
|
||||
if (!ref.current) return;
|
||||
|
||||
|
||||
const dragIndex = item.index;
|
||||
const hoverIndex = index;
|
||||
if (dragIndex === hoverIndex) return;
|
||||
|
||||
|
||||
const hoverBoundingRect = ref.current.getBoundingClientRect();
|
||||
const hoverMiddleY = (hoverBoundingRect.bottom - hoverBoundingRect.top) / 2;
|
||||
const clientOffset = monitor.getClientOffset();
|
||||
if (!clientOffset) return;
|
||||
|
||||
|
||||
const hoverClientY = clientOffset.y - hoverBoundingRect.top;
|
||||
|
||||
|
||||
if (dragIndex < hoverIndex && hoverClientY < hoverMiddleY) return;
|
||||
if (dragIndex > hoverIndex && hoverClientY > hoverMiddleY) return;
|
||||
|
||||
|
||||
moveRow(dragIndex, hoverIndex);
|
||||
item.index = hoverIndex;
|
||||
},
|
||||
|
|
@ -90,10 +89,21 @@ const DraggableColumnRow: React.FC<DraggableColumnRowProps> = ({ column, index,
|
|||
<TableCell>
|
||||
<Box sx={{ display: "flex" }}>
|
||||
<IconButton size="small" onClick={() => moveRow(index, index - 1)} disabled={isFirst}>
|
||||
<KeyboardArrowUpIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
transform: "rotate(180deg)",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => moveRow(index, index + 1)} disabled={isLast}>
|
||||
<KeyboardArrowDownIcon fontSize="small" />
|
||||
<ArrowDown
|
||||
sx={{
|
||||
width: "18px",
|
||||
height: "18px",
|
||||
}}
|
||||
/>
|
||||
</IconButton>
|
||||
<IconButton size="small" onClick={() => onDelete(index)} disabled={columns.length <= 1}>
|
||||
<Dismiss sx={{ width: "18px", height: "18px" }} />
|
||||
|
|
|
|||
Loading…
Reference in New Issue