mirror of
https://github.com/SECTL/SecScore.git
synced 2026-07-19 19:04:23 +08:00
feat: 优化分组编辑弹窗滚动并支持新建分组拖拽
This commit is contained in:
@@ -210,3 +210,17 @@ html.platform-macos #root {
|
||||
border-radius: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ss-group-board-modal .ant-modal {
|
||||
max-height: calc(100vh - 24px);
|
||||
}
|
||||
|
||||
.ss-group-board-modal .ant-modal-content {
|
||||
max-height: calc(100vh - 24px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.ss-group-board-modal .ant-modal-body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
Select,
|
||||
} from "antd"
|
||||
import type { ColumnsType } from "antd/es/table"
|
||||
import { UploadOutlined, MoreOutlined } from "@ant-design/icons"
|
||||
import { UploadOutlined, MoreOutlined, PlusOutlined } from "@ant-design/icons"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { TagEditorDialog } from "./TagEditorDialog"
|
||||
import { getAvatarFromExtraJson, setAvatarInExtraJson } from "../utils/studentAvatar"
|
||||
@@ -104,6 +104,7 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
|
||||
const [groupBoardSaving, setGroupBoardSaving] = useState(false)
|
||||
const [groupBoard, setGroupBoard] = useState<Record<string, student[]>>({})
|
||||
const [groupBoardOrder, setGroupBoardOrder] = useState<string[]>([])
|
||||
const [groupBoardNewGroupName, setGroupBoardNewGroupName] = useState("")
|
||||
const [pointerDraggingStudentId, setPointerDraggingStudentId] = useState<number | null>(null)
|
||||
const [pointerTargetGroup, setPointerTargetGroup] = useState<string | null>(null)
|
||||
const [pointerDragStudentName, setPointerDragStudentName] = useState("")
|
||||
@@ -378,9 +379,33 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
|
||||
})
|
||||
setGroupBoardOrder(order)
|
||||
setGroupBoard(board)
|
||||
setGroupBoardNewGroupName("")
|
||||
setGroupBoardVisible(true)
|
||||
}
|
||||
|
||||
const handleCreateGroupInBoard = () => {
|
||||
const name = groupBoardNewGroupName.trim()
|
||||
if (!name) {
|
||||
messageApi.warning(t("students.groupBoardGroupNameRequired"))
|
||||
return
|
||||
}
|
||||
if (name === UNGROUPED_KEY) {
|
||||
messageApi.warning(t("students.groupBoardGroupNameInvalid"))
|
||||
return
|
||||
}
|
||||
if (groupBoardOrder.includes(name)) {
|
||||
messageApi.warning(t("students.groupBoardGroupExists"))
|
||||
return
|
||||
}
|
||||
|
||||
setGroupBoard((prev) => ({ ...prev, [name]: [] }))
|
||||
setGroupBoardOrder((prev) => {
|
||||
const withoutUngrouped = prev.filter((key) => key !== UNGROUPED_KEY)
|
||||
return [...withoutUngrouped, name, UNGROUPED_KEY]
|
||||
})
|
||||
setGroupBoardNewGroupName("")
|
||||
}
|
||||
|
||||
const moveStudentToGroup = (studentId: number, targetGroup: string) => {
|
||||
setGroupBoard((prev) => {
|
||||
let movingStudent: student | null = null
|
||||
@@ -1356,6 +1381,7 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
|
||||
open={groupBoardVisible}
|
||||
onCancel={() => {
|
||||
setGroupBoardVisible(false)
|
||||
setGroupBoardNewGroupName("")
|
||||
draggingStudentIdRef.current = null
|
||||
pointerDragSourceGroupRef.current = null
|
||||
pointerDragTargetGroupRef.current = null
|
||||
@@ -1369,11 +1395,25 @@ export const StudentManager: React.FC<{ canEdit: boolean }> = ({ canEdit }) => {
|
||||
cancelText={t("common.cancel")}
|
||||
okButtonProps={{ loading: groupBoardSaving }}
|
||||
width="90%"
|
||||
wrapClassName="ss-group-board-modal"
|
||||
styles={{ body: { maxHeight: "calc(100vh - 220px)", overflowY: "auto" } }}
|
||||
destroyOnHidden
|
||||
>
|
||||
<div style={{ color: "var(--ss-text-secondary)", marginBottom: 12, fontSize: 12 }}>
|
||||
{t("students.groupBoardHint")}
|
||||
</div>
|
||||
<Space style={{ marginBottom: 12, width: "100%" }}>
|
||||
<Input
|
||||
value={groupBoardNewGroupName}
|
||||
onChange={(e) => setGroupBoardNewGroupName(e.target.value)}
|
||||
onPressEnter={handleCreateGroupInBoard}
|
||||
placeholder={t("students.groupBoardNewGroupPlaceholder")}
|
||||
maxLength={32}
|
||||
/>
|
||||
<Button icon={<PlusOutlined />} onClick={handleCreateGroupInBoard}>
|
||||
{t("students.groupBoardAddGroup")}
|
||||
</Button>
|
||||
</Space>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
|
||||
@@ -520,6 +520,11 @@
|
||||
"groupBoardEdit": "Edit Groups",
|
||||
"groupBoardTitle": "Quick Group Editor",
|
||||
"groupBoardHint": "Drag students across group columns and save to apply in batch.",
|
||||
"groupBoardNewGroupPlaceholder": "Enter new group name",
|
||||
"groupBoardAddGroup": "New Group",
|
||||
"groupBoardGroupExists": "Group already exists",
|
||||
"groupBoardGroupNameRequired": "Please enter group name",
|
||||
"groupBoardGroupNameInvalid": "Invalid group name",
|
||||
"groupBoardEmpty": "Drag students here",
|
||||
"groupBoardNoChanges": "No group changes",
|
||||
"groupBoardSaveSuccess": "Updated groups for {{count}} students",
|
||||
|
||||
@@ -520,6 +520,11 @@
|
||||
"groupBoardEdit": "编辑分组",
|
||||
"groupBoardTitle": "快速编辑分组",
|
||||
"groupBoardHint": "拖动学生到不同小组卡片中,点击保存后批量生效。",
|
||||
"groupBoardNewGroupPlaceholder": "输入新分组名称",
|
||||
"groupBoardAddGroup": "新建分组",
|
||||
"groupBoardGroupExists": "该分组已存在",
|
||||
"groupBoardGroupNameRequired": "请输入分组名称",
|
||||
"groupBoardGroupNameInvalid": "分组名称无效",
|
||||
"groupBoardEmpty": "可将学生拖拽到这里",
|
||||
"groupBoardNoChanges": "分组未发生变化",
|
||||
"groupBoardSaveSuccess": "已更新 {{count}} 名学生的小组",
|
||||
|
||||
Reference in New Issue
Block a user