From 692142a91089ed307d82f799303e1c1df883ce7f Mon Sep 17 00:00:00 2001 From: JSR Date: Thu, 26 Mar 2026 16:25:18 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E5=88=86=E7=BB=84?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=BC=B9=E7=AA=97=E6=BB=9A=E5=8A=A8=E5=B9=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=96=B0=E5=BB=BA=E5=88=86=E7=BB=84=E6=8B=96?= =?UTF-8?q?=E6=8B=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/main.css | 14 +++++++++++ src/components/StudentManager.tsx | 42 ++++++++++++++++++++++++++++++- src/i18n/locales/en-US.json | 5 ++++ src/i18n/locales/zh-CN.json | 5 ++++ 4 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/assets/main.css b/src/assets/main.css index 238b7b3..affddc1 100644 --- a/src/assets/main.css +++ b/src/assets/main.css @@ -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; +} diff --git a/src/components/StudentManager.tsx b/src/components/StudentManager.tsx index 444719e..e87f63f 100644 --- a/src/components/StudentManager.tsx +++ b/src/components/StudentManager.tsx @@ -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>({}) const [groupBoardOrder, setGroupBoardOrder] = useState([]) + const [groupBoardNewGroupName, setGroupBoardNewGroupName] = useState("") const [pointerDraggingStudentId, setPointerDraggingStudentId] = useState(null) const [pointerTargetGroup, setPointerTargetGroup] = useState(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 >
{t("students.groupBoardHint")}
+ + setGroupBoardNewGroupName(e.target.value)} + onPressEnter={handleCreateGroupInBoard} + placeholder={t("students.groupBoardNewGroupPlaceholder")} + maxLength={32} + /> + +