- Update E2E tests: announcements, auth, auth-business-flow, full-route-regression, grades, navigation, smoke-auth, teacher-web-test - Update integration tests: api-ai-chat, api-onboarding-complete, api-onboarding-status, proxy-guard, integration setup - Update visual regression tests: admin-dashboard, homepage, student-dashboard, teacher-dashboard, visual config, helpers - Update webapp tests: admin, parent, student full tests and debug scripts - Add new webapp tests: announcements_messages, settings_profile, debug scripts - Add webtest directory with test plans, screenshots, and diagnostic scripts
550 lines
62 KiB
JSON
550 lines
62 KiB
JSON
{
|
||
"test_date": "2026-06-22 19:36:55",
|
||
"module": "班级管理 (Class Management)",
|
||
"version": "v1",
|
||
"base_url": "http://localhost:3000",
|
||
"covered_submodules": [
|
||
"admin-classes",
|
||
"management-classes",
|
||
"teacher-classes",
|
||
"teacher-my-classes"
|
||
],
|
||
"summary": {
|
||
"total": 21,
|
||
"passed": 18,
|
||
"failed": 0,
|
||
"warnings": 3
|
||
},
|
||
"roles": {
|
||
"admin": {
|
||
"role": "admin",
|
||
"login_success": true,
|
||
"access_tests": [
|
||
{
|
||
"route_key": "admin_classes",
|
||
"url": "http://localhost:3000/admin/school/classes",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/admin/school/classes",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "页面正常加载",
|
||
"passed": true
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "management_classes",
|
||
"url": "http://localhost:3000/management/grade/classes",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/management/grade/classes",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "页面正常加载",
|
||
"passed": true
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_classes",
|
||
"url": "http://localhost:3000/teacher/classes",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/teacher/classes/my",
|
||
"status": "warning",
|
||
"errors": [],
|
||
"warnings": [
|
||
"重定向到 http://localhost:3000/teacher/classes/my(预期 /teacher/classes)"
|
||
],
|
||
"checks": []
|
||
},
|
||
{
|
||
"route_key": "teacher_my_classes",
|
||
"url": "http://localhost:3000/teacher/classes/my",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/teacher/classes/my",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "页面正常加载",
|
||
"passed": true
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"crud_tests": [
|
||
{
|
||
"feature": "admin 班级 CRUD",
|
||
"role": "admin",
|
||
"operations": [
|
||
{
|
||
"name": "列表加载",
|
||
"passed": true,
|
||
"detail": "列表/空状态正常显示"
|
||
},
|
||
{
|
||
"name": "打开创建对话框",
|
||
"passed": true,
|
||
"detail": "创建对话框已打开"
|
||
},
|
||
{
|
||
"name": "编辑入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
},
|
||
{
|
||
"name": "删除入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
}
|
||
],
|
||
"status": "passed",
|
||
"errors": []
|
||
},
|
||
{
|
||
"feature": "年级班级 CRUD (grade_head)",
|
||
"role": "admin",
|
||
"operations": [
|
||
{
|
||
"name": "列表加载",
|
||
"passed": false,
|
||
"detail": "未找到表格或空状态"
|
||
},
|
||
{
|
||
"name": "打开创建对话框",
|
||
"passed": false,
|
||
"detail": "异常: Locator.click: Timeout 30000ms exceeded.\nCall log:\n - waiting for locator(\"button:has-text(\\\"New\\\"), button:has-text(\\\"新建\\\"), button:has-text(\\\"Create\\\"), button:has-text(\\\"新增\\\")\").first\n - locator resolved to <button disabled data-slot=\"button\" class=\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 focus-visible:ring-4 focus-visible:outline-1 aria-invalid:focus-visible:ring-0 bg-primary text-primary-foreground shadow-sm hover:bg-primary/90 h-9…>…</button>\n - attempting click action\n 2 × waiting for element to be visible, enabled and stable\n - element is not enabled\n - retrying click action\n - waiting 20ms\n 2 × waiting for element to be visible, enabled and stable\n - element is not enabled\n - retrying click action\n - waiting 100ms\n 57 × waiting for element to be visible, enabled and stable\n - element is not enabled\n - retrying click action\n - waiting 500ms\n"
|
||
},
|
||
{
|
||
"name": "编辑入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
},
|
||
{
|
||
"name": "删除入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
}
|
||
],
|
||
"status": "warning",
|
||
"errors": []
|
||
}
|
||
],
|
||
"view_tests": [
|
||
{
|
||
"feature": "教师班级查看",
|
||
"role": "admin",
|
||
"operations": [
|
||
{
|
||
"name": "页面加载",
|
||
"passed": true,
|
||
"detail": "页面内容长度 401163"
|
||
},
|
||
{
|
||
"name": "班级卡片/列表存在",
|
||
"passed": true,
|
||
"detail": "找到卡片/表格/空状态(cards: 1, tables: 0, empty: 0)"
|
||
}
|
||
],
|
||
"status": "passed",
|
||
"errors": []
|
||
}
|
||
],
|
||
"errors": [],
|
||
"warnings": [
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran",
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran",
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran",
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran"
|
||
]
|
||
},
|
||
"teacher": {
|
||
"role": "teacher",
|
||
"login_success": true,
|
||
"access_tests": [
|
||
{
|
||
"route_key": "admin_classes",
|
||
"url": "http://localhost:3000/admin/school/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/teacher/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "management_classes",
|
||
"url": "http://localhost:3000/management/grade/classes",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/management/grade/classes",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "页面正常加载",
|
||
"passed": true
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_classes",
|
||
"url": "http://localhost:3000/teacher/classes",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/teacher/classes/my",
|
||
"status": "warning",
|
||
"errors": [],
|
||
"warnings": [
|
||
"重定向到 http://localhost:3000/teacher/classes/my(预期 /teacher/classes)"
|
||
],
|
||
"checks": []
|
||
},
|
||
{
|
||
"route_key": "teacher_my_classes",
|
||
"url": "http://localhost:3000/teacher/classes/my",
|
||
"expected_access": true,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/teacher/classes/my",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "页面正常加载",
|
||
"passed": true
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"crud_tests": [
|
||
{
|
||
"feature": "admin 班级 CRUD",
|
||
"role": "teacher",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"teacher 无 SCHOOL_MANAGE 权限,跳过 admin 班级 CRUD 测试"
|
||
]
|
||
},
|
||
{
|
||
"feature": "年级班级 CRUD (grade_head)",
|
||
"role": "teacher",
|
||
"operations": [
|
||
{
|
||
"name": "列表加载",
|
||
"passed": true,
|
||
"detail": "列表/空状态正常显示"
|
||
},
|
||
{
|
||
"name": "打开创建对话框",
|
||
"passed": true,
|
||
"detail": "创建对话框已打开"
|
||
},
|
||
{
|
||
"name": "编辑入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
},
|
||
{
|
||
"name": "删除入口存在",
|
||
"passed": true,
|
||
"detail": "无数据行,跳过"
|
||
}
|
||
],
|
||
"status": "passed",
|
||
"errors": []
|
||
}
|
||
],
|
||
"view_tests": [
|
||
{
|
||
"feature": "教师班级查看",
|
||
"role": "teacher",
|
||
"operations": [
|
||
{
|
||
"name": "页面加载",
|
||
"passed": true,
|
||
"detail": "页面内容长度 401708"
|
||
},
|
||
{
|
||
"name": "班级卡片/列表存在",
|
||
"passed": true,
|
||
"detail": "找到卡片/表格/空状态(cards: 5, tables: 0, empty: 0)"
|
||
}
|
||
],
|
||
"status": "passed",
|
||
"errors": []
|
||
}
|
||
],
|
||
"errors": [],
|
||
"warnings": [
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran",
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran"
|
||
]
|
||
},
|
||
"student": {
|
||
"role": "student",
|
||
"login_success": true,
|
||
"access_tests": [
|
||
{
|
||
"route_key": "admin_classes",
|
||
"url": "http://localhost:3000/admin/school/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "management_classes",
|
||
"url": "http://localhost:3000/management/grade/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/student/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_classes",
|
||
"url": "http://localhost:3000/teacher/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/student/dashboard?from=%2Fteacher%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fteacher%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_my_classes",
|
||
"url": "http://localhost:3000/teacher/classes/my",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/student/dashboard?from=%2Fteacher%2Fclasses%2Fmy&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/student/dashboard?from=%2Fteacher%2Fclasses%2Fmy&reason=forbidden"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"crud_tests": [
|
||
{
|
||
"feature": "admin 班级 CRUD",
|
||
"role": "student",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"student 无 SCHOOL_MANAGE 权限,跳过 admin 班级 CRUD 测试"
|
||
]
|
||
},
|
||
{
|
||
"feature": "年级班级 CRUD (grade_head)",
|
||
"role": "student",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"student 无 GRADE_MANAGE 权限,跳过 management 班级 CRUD 测试"
|
||
]
|
||
}
|
||
],
|
||
"view_tests": [
|
||
{
|
||
"feature": "教师班级查看",
|
||
"role": "student",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"student 无 CLASS_READ 权限,跳过教师班级查看测试"
|
||
]
|
||
}
|
||
],
|
||
"errors": [],
|
||
"warnings": []
|
||
},
|
||
"parent": {
|
||
"role": "parent",
|
||
"login_success": true,
|
||
"access_tests": [
|
||
{
|
||
"route_key": "admin_classes",
|
||
"url": "http://localhost:3000/admin/school/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fadmin%2Fschool%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "management_classes",
|
||
"url": "http://localhost:3000/management/grade/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fmanagement%2Fgrade%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_classes",
|
||
"url": "http://localhost:3000/teacher/classes",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fteacher%2Fclasses&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fteacher%2Fclasses&reason=forbidden"
|
||
}
|
||
]
|
||
},
|
||
{
|
||
"route_key": "teacher_my_classes",
|
||
"url": "http://localhost:3000/teacher/classes/my",
|
||
"expected_access": false,
|
||
"http_status": 200,
|
||
"final_url": "http://localhost:3000/parent/dashboard?from=%2Fteacher%2Fclasses%2Fmy&reason=forbidden",
|
||
"status": "passed",
|
||
"errors": [],
|
||
"warnings": [],
|
||
"checks": [
|
||
{
|
||
"name": "权限拒绝重定向",
|
||
"passed": true,
|
||
"detail": "正确重定向到 http://localhost:3000/parent/dashboard?from=%2Fteacher%2Fclasses%2Fmy&reason=forbidden"
|
||
}
|
||
]
|
||
}
|
||
],
|
||
"crud_tests": [
|
||
{
|
||
"feature": "admin 班级 CRUD",
|
||
"role": "parent",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"parent 无 SCHOOL_MANAGE 权限,跳过 admin 班级 CRUD 测试"
|
||
]
|
||
},
|
||
{
|
||
"feature": "年级班级 CRUD (grade_head)",
|
||
"role": "parent",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"parent 无 GRADE_MANAGE 权限,跳过 management 班级 CRUD 测试"
|
||
]
|
||
}
|
||
],
|
||
"view_tests": [
|
||
{
|
||
"feature": "教师班级查看",
|
||
"role": "parent",
|
||
"operations": [],
|
||
"status": "skipped",
|
||
"errors": [
|
||
"parent 无 CLASS_READ 权限,跳过教师班级查看测试"
|
||
]
|
||
}
|
||
],
|
||
"errors": [],
|
||
"warnings": [
|
||
"控制台错误: A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client bran"
|
||
]
|
||
}
|
||
},
|
||
"console_errors_global": [
|
||
{
|
||
"role": "admin",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <div className=\"flex items...\">\n <GlobalSearch>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"relative t...\" aria-label=\"通知\" type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n aria-label=\"通知\"\n type=\"button\"\n+ id=\"radix-_R_lebn6lb_\"\n- id=\"radix-_R_2lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" className=\"relative s...\" type=\"button\" id=\"radix-_R_t...\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm...\"}\n type=\"button\"\n+ id=\"radix-_R_tebn6lb_\"\n- id=\"radix-_R_3lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "admin",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <tbody ref={null} role=\"rowgroup\" className={\"[&_tr:la...\"}>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kd59bn5ritqbnubn6lb_\"\n- id=\"radix-_R_2hkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kl59bn5ritqbnubn6lb_\"\n- id=\"radix-_R_2ikl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kt59bn5ritqbnubn6lb_\"\n- id=\"radix-_R_2jkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_l559bn5ritqbnubn6lb_\"\n- id=\"radix-_R_2kkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "admin",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <tbody ref={null} role=\"rowgroup\" className={\"[&_tr:la...\"}>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kd59bn5ritpevqbn6lb_\"\n- id=\"radix-_R_2hkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kl59bn5ritpevqbn6lb_\"\n- id=\"radix-_R_2ikl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_k...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_kt59bn5ritpevqbn6lb_\"\n- id=\"radix-_R_2jkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"h-8 w-8\" disabled={false} type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n disabled={false}\n type=\"button\"\n+ id=\"radix-_R_l559bn5ritpevqbn6lb_\"\n- id=\"radix-_R_2kkl5esnebn9evqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "admin",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <div className=\"flex items...\">\n <GlobalSearch>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"relative t...\" aria-label=\"通知\" type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n aria-label=\"通知\"\n type=\"button\"\n+ id=\"radix-_R_lebn6lb_\"\n- id=\"radix-_R_2lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" className=\"relative s...\" type=\"button\" id=\"radix-_R_t...\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm...\"}\n type=\"button\"\n+ id=\"radix-_R_tebn6lb_\"\n- id=\"radix-_R_3lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "teacher",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <div className=\"flex items...\">\n <GlobalSearch>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"relative t...\" aria-label=\"通知\" type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n aria-label=\"通知\"\n type=\"button\"\n+ id=\"radix-_R_lebn6lb_\"\n- id=\"radix-_R_2lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" className=\"relative s...\" type=\"button\" id=\"radix-_R_t...\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm...\"}\n type=\"button\"\n+ id=\"radix-_R_tebn6lb_\"\n- id=\"radix-_R_3lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "teacher",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <div className=\"flex items...\">\n <GlobalSearch>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"relative t...\" aria-label=\"通知\" type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n aria-label=\"通知\"\n type=\"button\"\n+ id=\"radix-_R_lebn6lb_\"\n- id=\"radix-_R_2lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" className=\"relative s...\" type=\"button\" id=\"radix-_R_t...\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm...\"}\n type=\"button\"\n+ id=\"radix-_R_tebn6lb_\"\n- id=\"radix-_R_3lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
},
|
||
{
|
||
"role": "parent",
|
||
"error": "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:\n\n- A server/client branch `if (typeof window !== 'undefined')`.\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.\n- Date formatting in a user's locale which doesn't match the server.\n- External changing data without sending a snapshot of it along with the HTML.\n- Invalid HTML tag nesting.\n\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.\n\n%s%s https://react.dev/link/hydration-mismatch \n\n ...\n <div className=\"flex items...\">\n <GlobalSearch>\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_l...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" size=\"icon\" className=\"relative t...\" aria-label=\"通知\" type=\"button\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded...\"}\n aria-label=\"通知\"\n type=\"button\"\n+ id=\"radix-_R_lebn6lb_\"\n- id=\"radix-_R_2lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n ...\n <MenuProvider scope={{Menu:[...], ...}} onClose={function Menu.useCallback} isUsingKeyboardRef={{current:false}} ...>\n <DropdownMenuTrigger asChild={true}>\n <DropdownMenuTrigger data-slot=\"dropdown-m...\" asChild={true}>\n <MenuAnchor asChild={true} __scopeMenu={{Menu:[...], ...}}>\n <PopperAnchor __scopePopper={{Menu:[...], ...}} asChild={true} ref={null}>\n <Primitive.div asChild={true} ref={function}>\n <Primitive.div.Slot ref={function}>\n <Primitive.div.SlotClone ref={function}>\n <Primitive.button type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" aria-expanded={false} ...>\n <Primitive.button.Slot type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Primitive.button.SlotClone type=\"button\" id=\"radix-_R_t...\" aria-haspopup=\"menu\" ...>\n <Button variant=\"ghost\" className=\"relative s...\" type=\"button\" id=\"radix-_R_t...\" ...>\n <button\n data-slot=\"dropdown-menu-trigger\"\n className={\"inline-flex items-center justify-center gap-2 whitespace-nowrap text-sm...\"}\n type=\"button\"\n+ id=\"radix-_R_tebn6lb_\"\n- id=\"radix-_R_3lqbn6lb_\"\n aria-haspopup=\"menu\"\n aria-expanded={false}\n aria-controls={undefined}\n data-state=\"closed\"\n data-disabled={undefined}\n disabled={false}\n onPointerDown={function handleEvent}\n onKeyDown={function handleEvent}\n ref={function}\n >\n ...\n"
|
||
}
|
||
]
|
||
} |