-
Notifications
You must be signed in to change notification settings - Fork 495
Date picker fixed #912
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Date picker fixed #912
Conversation
add hour and minute
change default time to 08:00
update version
set right panel locale
Set first day of week
set default locale is enUS
change classname
change right panel click callback
Choose precise time to improve
dayjs replace moment
fix: caldaner width bug
fix: dayjs does not introduce the loaneData plugin
change click first or last year jump
feat: time second
…rst-day-of-week support customizing the first day of week
fix: code problems
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Walkthrough本次更改将日期处理库从 moment.js 全面替换为 dayjs,并引入了 dayjs 的多种插件以支持本地化、UTC、周数等功能。同时,增加了右侧小时-分钟选择面板(showHourAndMinute),并支持自定义一周的起始日。相关的类型定义、示例代码、样式文件、测试文件及文档均已同步更新。 Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Calendar
participant CalendarRightPanel
participant ParentComponent
User->>Calendar: 打开日历组件
Calendar->>CalendarRightPanel: (若 showHourAndMinute) 渲染右侧时间面板
User->>CalendarRightPanel: 点击某个小时-分钟选项
CalendarRightPanel->>Calendar: onSelect(选中时间)
CalendarRightPanel->>ParentComponent: onClickRightPanelTime()
ParentComponent->>Calendar: 关闭日历(如有需要)
Poem
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 17
🔭 Outside diff range comments (1)
tests/Calendar.spec.jsx (1)
230-238
:⚠️ Potential issue删除重复的测试用例
这个 "left works" 测试用例与第 204-212 行的测试完全重复。
删除这个重复的测试用例:
-it('left works', () => { - const original = calendar.state().value; - let expected = original.clone(); - expected = expected.add(-1, 'day'); - - calendar.simulate('keyDown', { keyCode: keyCode.LEFT }); - expect(calendar.state().value.date()).toBe(expected.date()); - expect(input.getDOMNode().value).toBe(''); -});
🧹 Nitpick comments (2)
src/util/dayjs.js (1)
11-17
: dayjs 插件扩展与导出
已对核心实例进行插件扩展并导出,建议若需进一步支持时区,可额外引入timezone
插件。tests/Calendar.spec.jsx (1)
206-207
: 可以简化 dayjs 的不可变操作当前的模式虽然正确,但可以更简洁。dayjs 的方法返回新实例,可以直接赋值。
可以将这种模式:
-let expected = original.clone(); -expected = expected.add(1, 'day'); +const expected = original.clone().add(1, 'day');或者如果需要保持
let
:-let expected = original.clone(); -expected = expected.add(1, 'day'); +let expected = original.add(1, 'day');Also applies to: 217-218, 226-227, 232-233, 243-244, 252-253, 261-262, 270-271, 279-280, 288-289, 300-301
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
tests/__snapshots__/Calendar.spec.jsx.snap
is excluded by!**/*.snap
tests/__snapshots__/FullCalendar.spec.js.snap
is excluded by!**/*.snap
tests/__snapshots__/RangeCalendar.spec.jsx.snap
is excluded by!**/*.snap
tests/__snapshots__/locale.spec.js.snap
is excluded by!**/*.snap
📒 Files selected for processing (44)
.travis.yml
(1 hunks)README.md
(3 hunks)assets/common/FullCalendar.less
(2 hunks)assets/index/Calendar.less
(8 hunks)assets/index/DecadePanel.less
(2 hunks)assets/index/Input.less
(1 hunks)assets/index/MonthPanel.less
(3 hunks)assets/index/TimePanel.less
(1 hunks)assets/index/YearPanel.less
(2 hunks)examples/antd-calendar.js
(5 hunks)examples/antd-month-calendar.js
(1 hunks)examples/antd-range-calendar.js
(3 hunks)examples/control-panel.js
(1 hunks)examples/custom-clear-icon.js
(1 hunks)examples/full-calendar.js
(1 hunks)examples/getCalendarContainer.js
(1 hunks)examples/start-end-range.js
(1 hunks)examples/start-end.js
(1 hunks)examples/week.js
(4 hunks)index.d.ts
(1 hunks)package.json
(3 hunks)rc-calendar-tests.tsx
(1 hunks)src/Calendar.jsx
(9 hunks)src/FullCalendar.jsx
(2 hunks)src/MonthCalendar.jsx
(3 hunks)src/RangeCalendar.js
(4 hunks)src/calendar/CalendarHeader.jsx
(1 hunks)src/calendar/CalendarRightPanel.jsx
(1 hunks)src/date/DateConstants.js
(1 hunks)src/date/DateInput.js
(6 hunks)src/date/DateTBody.jsx
(6 hunks)src/date/DateTHead.jsx
(2 hunks)src/decade/DecadePanel.jsx
(1 hunks)src/full-calendar/CalendarHeader.jsx
(2 hunks)src/mixin/CalendarMixin.js
(2 hunks)src/month/MonthTable.js
(4 hunks)src/util/dayjs.js
(1 hunks)src/util/index.js
(3 hunks)src/year/YearPanel.jsx
(2 hunks)tests/Calendar.spec.jsx
(17 hunks)tests/FullCalendar.spec.js
(2 hunks)tests/MonthCalendar.spec.js
(4 hunks)tests/Picker.spec.jsx
(12 hunks)tests/RangeCalendar.spec.jsx
(26 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/date/DateInput.js (2)
src/year/YearPanel.jsx (2)
value
(8-8)value
(16-16)src/util/index.js (1)
formatDate
(97-107)
examples/antd-calendar.js (3)
examples/antd-month-calendar.js (3)
format
(15-15)cn
(16-16)now
(18-18)examples/start-end.js (4)
format
(16-16)cn
(17-17)now
(19-19)timePickerElement
(34-34)examples/antd-range-calendar.js (4)
cn
(15-15)now
(23-23)timePickerElement
(33-37)date
(48-48)
src/Calendar.jsx (3)
src/mixin/CalendarMixin.js (2)
calendarMixinDefaultProps
(26-28)calendarMixinDefaultProps
(26-28)src/mixin/CommonMixin.js (2)
defaultProp
(18-33)defaultProp
(18-33)src/calendar/CalendarRightPanel.jsx (1)
CalendarRightPanel
(5-91)
src/date/DateTBody.jsx (2)
src/date/DateTHead.jsx (1)
DateConstants
(4-4)src/date/DateConstants.js (2)
DAY_NAME_TO_INDEX
(6-14)DATE_ROW_COLUMN_COUNT
(1-4)
🔇 Additional comments (113)
.travis.yml (1)
7-7
: 更新 Travis 通知邮箱
仅保留bing.an@seafile.com
,清理了旧的收件人列表,符合项目重命名与迁移需求。src/mixin/CalendarMixin.js (1)
15-15
: 初始化当前时间符合预期
getNowByCurrentStateValue
使用dayjs()
获取当前日期/时间,与其他组件保持一致,逻辑正确。src/FullCalendar.jsx (2)
14-14
: 正确引入已配置的 dayjs 实例
从本地./util/dayjs
导入,保证与全局配置插件一致,已正确实现。
64-64
: 默认值使用 dayjs() 获取当前时间
value: props.value || props.defaultValue || dayjs()
初始化逻辑清晰且符合预期。tests/FullCalendar.spec.js (2)
5-5
: 测试中引入已配置的 dayjs 实例
import dayjs from '../src/util/dayjs';
保持与源码相同的配置,正确使用。
85-85
: 更新测试以使用 dayjs
const selected = dayjs().add(1, 'month');
与生产代码一致,测试逻辑正确。tests/MonthCalendar.spec.js (3)
6-6
: 验证 dayjs 导入路径正确性导入路径看起来正确,从本地工具目录导入 dayjs 实例。这种做法可以确保所有组件使用统一配置的 dayjs 实例。
117-117
: dayjs 构造函数使用正确dayjs 构造函数的使用方式与 moment.js 相同,可以直接传入日期字符串。这些用法在测试中是正确的。
Also applies to: 120-120
22-22
:✅ Verification successful
dayjs API 兼容性检查
dayjs 的
add()
方法与 moment.js 兼容。但需要确认dayjs实例是否正确配置了所需的插件,特别是用于月份操作的插件。验证 dayjs 配置是否包含必要的插件:
Also applies to: 41-41
🏁 Script executed:
#!/bin/bash # 检查 dayjs 工具文件中是否正确配置了插件 cat src/util/dayjs.jsLength of output: 599
不需要额外插件来支持 dayjs 的 add 方法
已检查
src/util/dayjs.js
,其中已按需引入并扩展了 localeData、weekOfYear、utc、advancedFormat、customParseFormat、badMutable 等插件。dayjs().add(2, 'month')
属于 core API,无需额外插件即可正常使用,可忽略此处关于缺少插件的担忧。examples/control-panel.js (1)
2-2
: 包路径迁移正确样式文件的导入路径已正确更新为新的包名
@seafile/seafile-calendar
。这与整体的包重命名策略一致。examples/full-calendar.js (3)
3-3
: 导入路径全面更新所有相关的导入路径都已正确更新为新的包名。这包括样式文件、组件和语言包,保持了一致性。
Also applies to: 6-6, 11-12
14-14
: dayjs 工具导入使用相对路径导入 dayjs 工具是正确的做法,确保了配置的一致性。
19-24
:✅ Verification successful
验证 dayjs 的语言环境和时区设置
dayjs 的
locale()
和utcOffset()
方法使用看起来正确,但需要确认 dayjs 是否正确配置了语言环境和 UTC 插件。验证 dayjs 配置中是否包含必要的插件:
🏁 Script executed:
#!/bin/bash # 检查 dayjs 配置文件中的插件设置 grep -n "locale\|utc" src/util/dayjs.jsLength of output: 244
确认 dayjs 插件配置无误
src/util/dayjs.js
已正确引入并扩展dayjs/plugin/localeData
和dayjs/plugin/utc
- 已导入
dayjs/locale/zh-cn
与dayjs/locale/en-gb
因此,
examples/full-calendar.js
中对locale()
和utcOffset()
的调用均可正常工作,无需进一步修改。examples/start-end-range.js (3)
3-3
: 范围日历导入路径更新所有组件和样式的导入路径都已正确更新。RangeCalendar 和 DatePicker 组件的导入路径保持一致。
Also applies to: 6-7, 9-10
12-12
: dayjs 工具导入一致性与其他示例文件保持一致,正确使用相对路径导入 dayjs 工具。
19-24
:❓ Verification inconclusive
语言环境配置验证
dayjs 实例的语言环境和时区配置与之前的 moment.js 用法保持一致。需要确认所有语言环境相关的功能正常工作。
建议运行以下脚本验证语言环境配置:
🏁 Script executed:
#!/bin/bash # 检查语言包文件是否存在且格式正确 ls -la src/locale/zh_CN.js src/locale/en_US.jsLength of output: 184
请确认 Day.js 语言环境和时区配置
- 已检查并确认:
src/locale/zh_CN.js
和src/locale/en_US.js
文件存在且格式正确。- 建议新增简单验证脚本,输出不同 locale 和时区下的格式,确保行为与此前的 Moment.js 保持一致。例如:
# 安装 dayjs 及所需插件后执行 node -e " const dayjs = require('dayjs'); require('dayjs/locale/zh-cn'); require('dayjs/locale/en-gb'); console.log('zh-cn (UTC+8):', dayjs().locale('zh-cn').utcOffset(8).format()); console.log('en-gb (UTC+0):', dayjs().locale('en-gb').utcOffset(0).format()); "- 若输出符合预期,即可放心合并。
src/calendar/CalendarHeader.jsx (2)
9-11
: 日期处理逻辑正确实现了不可变API模式这个修改正确地适配了dayjs的不可变API。使用
let
声明变量并重新赋值add
方法的返回值是正确的做法,因为dayjs方法返回新的实例而不是修改原对象。
15-17
: 年份操作也正确实现了不可变API模式与月份操作一致,正确地处理了dayjs的不可变特性。
examples/start-end.js (2)
3-14
: 包导入迁移正确且一致从
rc-calendar
到@seafile/seafile-calendar
的包迁移是一致的,dayjs工具的导入也正确。这些变更与整个代码库的迁移策略保持一致。
19-24
: dayjs初始化和本地化设置正确dayjs的初始化和locale、utcOffset设置保持了与之前moment.js相同的功能,实现正确。
examples/getCalendarContainer.js (2)
1-12
: 导入迁移与其他示例文件保持一致所有的包导入更新都与项目中其他示例文件保持一致,从
rc-calendar
迁移到@seafile/seafile-calendar
,从moment
迁移到本地的dayjs
工具。
17-22
: dayjs初始化逻辑正确dayjs的初始化和配置逻辑与其他文件保持一致,正确实现了原有的功能。
assets/index/MonthPanel.less (1)
114-114
: 主题颜色更新符合设计规范从蓝色调到橙色/黄色调的颜色主题更新是一致的,这些颜色值都是有效的十六进制代码,与整个日历组件的视觉主题更新保持一致。
Also applies to: 132-132, 136-136
assets/index/TimePanel.less (3)
60-60
: 配色更新一致
.@{prefixClass}-time-panel-time:hover
背景色由蓝色调整为#fcecd9
,与整体橙色主题保持一致。
67-67
: 选中单元格背景色更新
.@{prefixClass}-time-panel-selected-cell .@{prefixClass}-time-panel-time
的背景色更换为#f09f3f
,与新版主题色相符。
71-71
: 选中单元格悬浮样式一致性
选中状态下的悬浮背景也设置为#f09f3f
,保持交互反馈一致。assets/index/DecadePanel.less (3)
98-101
: 配色更新一致
.@{prefixClass}-decade-panel-decade:hover
背景色改为#fcecd9
,符合新主题橙色调。
104-107
: 选中单元格背景色更新
.@{prefixClass}-decade-panel-selected-cell .@{prefixClass}-decade-panel-decade
背景色改为#f09f3f
并保持文字为白色。
108-112
: 选中单元格悬浮样式一致性
选中状态下的悬浮背景也设置为#f09f3f,color: #fff
,确保交互体验统一。assets/index/YearPanel.less (3)
112-115
: 配色更新一致
.@{prefixClass}-year-panel-year:hover
背景色由蓝色改为#fcecd9
,符合整体橙色主题。
118-121
: 选中单元格背景色更新
.@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year
背景色更新为#f09f3f
,文字保持白色。
122-125
: 选中单元格悬浮样式一致性
选中状态下悬浮背景与选中背景一致,增强视觉反馈。tests/RangeCalendar.spec.jsx (1)
7-7
: 测试迁移:Moment → Day.js
已将所有import moment
及相关用法替换为import dayjs
,并引入了自定义format
、.clone()
、.add()
等方法,配合customParseFormat
插件保证格式解析。所有断言和快照均已更新以匹配 Day.js 的 API 和不可变特性,测试逻辑一致且无明显缺失。Also applies to: 28-28, 146-147, 150-150, 159-160, 162-163, 167-168, 171-171, 181-181, 184-186, 203-204, 213-214, 225-225, 297-298, 325-326, 434-434, 446-446, 458-458, 470-470, 505-506, 516-517, 534-534, 538-538, 548-550, 582-582, 762-762, 789-789, 815-815
src/util/dayjs.js (1)
1-9
: 依赖及插件导入
集中导入dayjs
核心和localeData
、weekOfYear
、utc
、advancedFormat
、customParseFormat
、badMutable
等插件,并加载中英文 locale,符合项目需求。src/decade/DecadePanel.jsx (2)
8-9
: 正确实现了dayjs不可变API的处理这个修改正确地将dayjs的
add
方法结果重新赋值给next
变量,符合dayjs不可变API的设计。这是从moment.js迁移到dayjs的正确模式。
16-18
: 正确处理了dayjs的链式操作这些修改正确地处理了dayjs的不可变操作,每次调用
year()
和month()
方法后都重新赋值给next
变量。这确保了日期对象的正确更新。rc-calendar-tests.tsx (4)
2-2
: 正确更新了导入语句将导入从moment.js更改为dayjs,与整个代码库的迁移保持一致。
5-5
: 正确更新了类型注解将函数参数的类型从moment类型更新为
dayjs.Dayjs
,确保类型安全。
13-13
: 正确更新了默认值构造将默认值从
moment()
更改为dayjs()
,与新的日期库保持一致。
17-17
: 正确更新了回调函数类型
disabledDate
回调函数的参数类型正确地更新为dayjs.Dayjs
。src/date/DateConstants.js (3)
1-4
: 良好的常量重组将日期行列数常量重新组织到
DATE_ROW_COLUMN_COUNT
对象中,提高了代码的组织性和可读性。
6-14
: 有用的新增映射常量新增的
DAY_NAME_TO_INDEX
映射为星期名称到索引的转换提供了便利,支持了日历组件中自定义一周起始日的功能。
16-19
: 清晰的导出结构新的导出结构更加清晰,将相关常量分组导出,便于其他组件使用。
src/MonthCalendar.jsx (8)
13-13
: 正确使用本地dayjs工具模块从moment.js迁移到本地的dayjs工具模块,确保了统一的日期处理配置和插件支持。
34-34
: 正确更新初始状态值将初始状态值从
moment()
更改为dayjs()
,与新的日期库保持一致。
48-48
: 正确处理dayjs不可变操作将
add
方法的结果重新赋值给value
变量,正确实现了dayjs不可变API的处理模式。
52-52
: 正确处理向上箭头键的日期计算正确地将
add(-3, 'months')
的结果重新赋值,确保日期计算的正确性。
57-57
: 正确处理Ctrl+左箭头的年份计算正确地将年份减法操作的结果重新赋值给
value
变量。
59-59
: 正确处理左箭头键的月份计算正确地将月份减法操作的结果重新赋值,遵循dayjs不可变API模式。
65-65
: 正确处理Ctrl+右箭头的年份计算正确地将年份加法操作的结果重新赋值给
value
变量。
67-67
: 正确处理右箭头键的月份计算正确地将月份加法操作的结果重新赋值,确保键盘导航功能的正确性。
examples/antd-month-calendar.js (1)
3-18
: 迁移到 dayjs 的导入更改看起来正确从 rc-calendar 到 @seafile/seafile-calendar 的包迁移以及从 moment 到 dayjs 的日期库迁移都是一致的。导入路径和初始化代码都正确更新了。
examples/custom-clear-icon.js (1)
3-11
: 导入路径更新正确包名和日期库的导入更改都是一致的,符合从 moment 到 dayjs 的迁移模式。
src/full-calendar/CalendarHeader.jsx (3)
10-12
: 正确处理 dayjs 的不可变性这个更改对于从 moment 迁移到 dayjs 至关重要。dayjs 是不可变的,所以必须重新赋值方法调用的结果,而不是依赖就地修改。
16-18
: 月份更改方法正确更新与年份更改方法类似,正确实现了 dayjs 不可变 API 的重新赋值模式。
47-53
: 月份选择元素中的不可变处理在月份循环中正确使用了重新赋值模式来处理 dayjs 的不可变性。这确保每次迭代都正确设置月份值。
tests/Picker.spec.jsx (3)
86-88
: 测试期望值的重大变化需要验证测试期望从月份 5(6月)、日期 1 更改为月份 3(4月)、日期 28。这种重大变化可能表明:
- dayjs 数组初始化行为与 moment 不同
- 测试期望值更新不正确
- 日期处理逻辑中存在错误
需要验证这些更改是否正确反映了预期的行为。
111-116
: 范围选择器测试中的类似期望值变化与单日期选择器测试类似,这里的期望值也发生了重大变化。需要确保这些更改与实际的 dayjs 行为一致。
137-142
: 受控值测试中的 dayjs 使用这里的 dayjs 使用看起来正确,使用了
.clone()
和.add()
方法,符合不可变 API 的使用模式。package.json (3)
2-3
: 包重命名和版本重置正确包名从 "rc-calendar" 更改为 "@seafile/seafile-calendar",版本重置为 "0.0.29",这对于包的重新品牌化是合理的。
23-30
: 元数据更新一致主页、作者、仓库和 bug 报告 URL 都已正确更新为指向 Seafile 的 GitHub 资源。
101-103
: 类型定义和覆盖配置合理添加了 types 字段和 graceful-fs 的覆盖版本,这些配置是合理的。
examples/antd-range-calendar.js (4)
5-10
: 导入语句迁移正确从 'rc-calendar' 到 '@seafile/seafile-calendar' 的导入更改是一致的,包括组件、语言包和样式文件。
13-13
: dayjs 迁移实现正确从 moment 到 dayjs 的迁移实现正确:
- 正确导入本地 dayjs 工具
- 语言设置从
moment.locale
更新为dayjs.locale
- 日期初始化从
moment()
更新为dayjs()
Also applies to: 18-21, 23-23
35-35
: 时间选择器默认值更新正确时间选择器的默认值正确地从 moment 更新为 dayjs,保持了相同的时间格式。
47-53
: 正确处理 dayjs 不可变特性在
disabledDate
函数中正确处理了 dayjs 的不可变特性,通过重新赋值来应用 hour、minute 和 second 的修改。这是 dayjs 迁移的最佳实践。src/year/YearPanel.jsx (3)
7-13
: 正确处理不可变日期操作在
goYear
函数中正确处理了 dayjs 的不可变特性,通过重新赋值value = value.add(direction, 'year')
来应用日期变更。
15-23
: 年份选择逻辑正确实现在
chooseYear
函数中正确实现了不可变操作:
- 克隆当前值
- 分别设置年份和月份并重新赋值
- 保持了原有的功能逻辑
79-79
: 简化点击处理逻辑移除了基于十年关系的条件处理程序,简化了年份单元格的点击处理,使代码更清晰。
src/RangeCalendar.js (4)
13-13
: 导入语句更新正确从 moment 到本地 dayjs 工具的导入更改是正确的,与整个代码库的迁移策略一致。
53-53
: 默认锚点初始化更新在
normalizeAnchor
函数中,默认日期初始化从moment()
正确更新为dayjs()
,保持了创建当前日期和下个月日期的逻辑。
213-213
: 键盘导航默认时间更新在
onKeyDown
方法的updateHoverPoint
函数中,默认当前时间初始化从moment()
正确更新为dayjs()
。
574-574
: 选择值变更处理更新在
fireSelectValueChange
方法中,起始值的默认初始化从moment()
正确更新为dayjs()
,保持了原有的逻辑。assets/common/FullCalendar.less (1)
27-28
: 颜色主题更新看起来不错从蓝色主题到橙色主题的系统性更新是一致的,符合整个日历组件的视觉风格统一。
Also applies to: 82-82, 87-88
src/month/MonthTable.js (3)
10-11
: 正确处理了不可变日期对象从可变的 moment.js 迁移到不可变的 dayjs 后,正确地使用了重新赋值模式。这确保了
.month()
方法返回的新对象被正确捕获。
45-45
: 月份循环中的不可变对象处理在生成月份数据时正确地处理了 dayjs 的不可变特性,每次调用
.month(index)
都重新赋值给current
变量。Also applies to: 51-51
75-76
: 渲染逻辑中的一致性处理在禁用日期检查、单元格渲染和内容渲染中都一致地使用了 dayjs 的不可变对象模式,确保了日期操作的正确性。
Also applies to: 88-89, 94-95
src/date/DateInput.js (4)
6-6
: 成功迁移到 dayjs正确地将日期库从 moment 替换为 dayjs,这与整个项目的迁移保持一致。
43-46
: 简化了状态管理移除了
invalid
状态标志及相关的无效输入处理逻辑,简化了组件的状态管理。现在只需要跟踪输入字符串和焦点状态,使组件更加简洁。Also applies to: 63-63, 70-70, 84-84, 91-91
68-68
: 使用 dayjs 严格解析正确地使用 dayjs 的严格解析模式 (
dayjs(str, format, true)
),这确保了只有完全匹配格式的输入才会被认为是有效的。
74-81
: 正确处理不可变日期对象链式调用正确地使用了 dayjs 的不可变特性,通过链式调用创建新的日期对象,而不是修改原始对象。这种模式确保了日期操作的安全性。
src/util/index.js (2)
1-4
: 正确配置了 dayjs 及其插件成功地将导入从 moment 迁移到 dayjs,并正确地扩展了 UTC 插件以支持时区功能。
19-21
: getTodayTime 函数正确处理不可变对象正确地使用了 dayjs 的不可变特性,通过重新赋值来设置 locale 和 utcOffset。
examples/week.js (4)
3-12
: 导入语句更新正确从
rc-calendar
到@seafile/seafile-calendar
的包名更新以及从 moment 到 dayjs 的迁移都处理得很好。
28-34
: CSS类名更新符合包重命名CSS选择器正确更新为新的包命名空间前缀,保持了样式的一致性。
Also applies to: 46-46
92-93
: 正确修复了dayjs的不可变性问题将
add(-1, 'weeks')
的结果重新赋值给value
变量是正确的,因为 dayjs 对象是不可变的,这修复了之前可能存在的突变问题。
14-14
:❓ Verification inconclusive
验证日期格式字符串的兼容性
格式从
'YYYY-Wo'
改为'YYYY-wo'
,需要确认 dayjs 的周格式化与 moment.js 的行为是否一致,以避免潜在的破坏性变更。
🏁 Script executed:
#!/bin/bash # 描述:验证dayjs和moment.js的周格式化行为是否一致 # 期望:两个库的周格式化输出应该匹配 # 搜索其他使用周格式的地方 rg -A 3 -B 3 "wo|Wo" --type jsLength of output: 19774
🏁 Script executed:
#!/bin/bash # 在 src/util 目录中查找 dayjs 工具文件并显示前200行内容 for f in $(fd dayjs src/util); do echo "=== FILE: $f ===" sed -n '1,200p' "$f" doneLength of output: 735
验证 weekOfYear 在 dayjs 与 moment 中格式化行为一致性
格式从'YYYY-Wo'
改为'YYYY-wo'
,需要确认 dayjs 的 weekOfYear 插件对于小写wo
是否与 moment.js 的大写Wo
行为一致,以避免潜在的破坏性变更。
- 文件:
examples/week.js
,第 14 行src/util/dayjs.js
已正确引入weekOfYear
插件,但尚需对格式输出进行对比测试。建议:在年初、年末等边界日期,分别使用:
dayjs(date).format('YYYY-wo'); moment(date).format('YYYY-Wo');对输出结果进行比对,确保两者一致。
src/date/DateTHead.jsx (3)
4-4
: 引入常量提升性能使用
DAY_NAME_TO_INDEX
和DATE_ROW_COLUMN_COUNT
常量替代动态计算,这是一个很好的性能优化。
15-21
: 静态周数据获取和一周开始日处理使用静态方法获取周数据数组,以及对
firstDayOfWeek
属性的字符串规范化处理(首字母大写+回退到Sunday)都实现得很好。
24-29
: 高效的周循环实现使用模运算
(firstDay + dateColIndex) % dateColumnCount
来循环遍历周数据是一个优雅且高效的实现方式。README.md (3)
198-203
: 新增 showHourAndMinute 属性文档新属性的文档描述清晰,包含了类型、默认值和用途说明。特别说明了这是为 dtable 日期列设计的功能。
234-239
: 新增 onClickRightPanelTime 回调文档回调函数的文档完整,正确说明了只有在
showHourAndMinute
为 true 时才会触发。
759-761
: Node.js 版本要求更新合理将最低 Node.js 版本要求更新到 18.20.4 符合现代开发的需要。
assets/index/Calendar.less (4)
5-5
: 容器宽度改为动态适应使用
fit-content
替代固定宽度是一个很好的改进,让容器能够根据内容动态调整大小。
18-26
: 新增弹性布局支持为
.date-panel
和.date-panel-container
添加display: flex
支持新的右侧面板布局,同时显式设置.date-panel
和.panel
为display: block
保持向后兼容性。
136-195
: 全面的右侧面板样式实现新增的右侧面板样式包含了完整的头部、主体和底部区域,支持滚动、悬停状态和选中效果。样式结构合理且功能完整。
252-252
:✅ Verification successful
验证橙色主题的一致性
整个日历组件的色彩主题从蓝色系统性地更改为橙色系,请确保所有相关的样式文件都进行了一致的颜色更新。
Also applies to: 256-256, 259-259, 264-264
🏁 Script executed:
#!/bin/bash # 描述:检查是否还有遗留的蓝色主题颜色值 # 期望:找到需要更新的蓝色颜色值 # 搜索可能遗留的蓝色主题颜色 rg "#23c0fa|#3fc7fa|#ebfaff" --type css --type lessLength of output: 53
🏁 Script executed:
#!/bin/bash # 再次检查常见蓝色十六进制(大小写不敏感)及 “blue” 关键字、CSS 变量中是否残留蓝色主题 rg -i '#23c0fa|#3fc7fa|#ebfaff' --type css --type less rg -i 'blue' --type css --type less rg '@[A-Za-z0-9_-]*blue' --type lessLength of output: 131
确认无残留蓝色主题
已通过对.less
/.css
文件中十六进制颜色、blue
关键字及 CSS 变量名的全局搜索,未发现任何旧蓝色配色。日历组件样式已全部切换为橙色系,无需进一步修改。tests/Calendar.spec.jsx (1)
4-4
: 导入路径正确从相对路径导入自定义的 dayjs 工具模块是合理的做法,可以集中管理 dayjs 的配置和插件。
src/date/DateTBody.jsx (1)
90-91
: 使用常量提高了代码的可维护性将硬编码的行列数替换为常量是很好的做法,使代码更易于维护和配置。
Also applies to: 104-104, 120-120, 124-124
examples/antd-calendar.js (3)
3-13
: 导入路径迁移正确从
rc-calendar
迁移到@seafile/seafile-calendar
的导入路径更改是正确的,与整体迁移策略一致。
129-131
: 新增的时间面板功能实现正确
onClickRightPanelTime
方法和相关属性的实现简洁明了,正确地处理了点击右侧时间面板后关闭日历的功能。Also applies to: 154-155
57-61
: 日期禁用逻辑迁移正确正确地使用了 dayjs 的不可变 API 来设置时间为 0,逻辑保持不变。
index.d.ts (3)
7-7
: 类型定义更新正确!从 Moment 迁移到 Dayjs 的类型定义更新一致且完整。
Also applies to: 15-17, 25-25, 32-36
28-28
: 新增回调属性定义正确!
onClickRightPanelTime
回调与新增的右侧时间选择面板功能对应。
39-39
: TypeScript 类型修正正确!将
String
修正为string
符合 TypeScript 的类型定义规范。src/calendar/CalendarRightPanel.jsx (3)
5-14
: 组件结构定义良好!PropTypes 定义完整,涵盖了所有必要的属性。
32-38
: 选择处理逻辑正确!正确更新状态并触发相应的回调函数。
40-49
: 时间生成逻辑实现正确!使用
padStart
确保时间格式的一致性是个好做法。src/Calendar.jsx (5)
6-6
: Dayjs 配置正确!正确导入并扩展了所需的 dayjs 插件。
Also applies to: 21-26
31-36
: 日期验证函数更新正确!正确地从 Moment 验证逻辑迁移到 Dayjs 验证逻辑。
55-56
: 新增属性定义完整!新增的时间面板相关属性定义清晰,默认值设置合理。
Also applies to: 74-75, 83-83, 87-87, 89-89
99-99
: 状态初始化更新正确!正确使用
dayjs()
替代moment()
获取当前时间。
290-292
: 渲染逻辑实现出色!正确实现了:
- 新属性的解构
- 条件渲染右侧时间面板
- 向子组件传递所需属性
- 使用容器 div 包装面板布局
实现清晰且遵循 React 最佳实践。
Also applies to: 346-416
border-color: #f09f4g; | ||
} | ||
|
||
&:focus { | ||
border-color: #23c0fa; | ||
box-shadow: 0 0 3px #23c0fa; | ||
border-color: #f09f4g; | ||
box-shadow: 0 0 3px #f09f4g; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
无效的十六进制颜色值
你使用了 #f09f4g
,其中字符 g
并不在合法的 0–9/A–F 范围内,CSS 解析会失败。请修正为合法的十六进制值,例如:
-&:hover {
- border-color: #f09f4g;
-}
+&:hover {
+ border-color: #f09f4f; /* 示例:将最后一位 g 改为合法的 0–F */
+}
-&:focus {
- border-color: #f09f4g;
- box-shadow: 0 0 3px #f09f4g;
-}
+&:focus {
+ border-color: #f09f4f;
+ box-shadow: 0 0 3px #f09f4f;
+}
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
border-color: #f09f4g; | |
} | |
&:focus { | |
border-color: #23c0fa; | |
box-shadow: 0 0 3px #23c0fa; | |
border-color: #f09f4g; | |
box-shadow: 0 0 3px #f09f4g; | |
} | |
&:hover { | |
border-color: #f09f4f; /* 示例:将最后一位 g 改为合法的 0–F */ | |
} | |
&:focus { | |
border-color: #f09f4f; | |
box-shadow: 0 0 3px #f09f4f; | |
} |
🤖 Prompt for AI Agents
In assets/index/Input.less around lines 15 to 21, the color code #f09f4g is
invalid because 'g' is not a valid hexadecimal character. Replace all instances
of #f09f4g with a valid hex color code, such as #f09f46 or another appropriate
color value within 0-9 and A-F.
src/mixin/CalendarMixin.js
Outdated
@@ -1,7 +1,7 @@ | |||
import React from 'react'; | |||
import PropTypes from 'prop-types'; | |||
import classnames from 'classnames'; | |||
import moment from 'moment'; | |||
import dayjs from 'dayjs'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复 dayjs 引入路径
当前直接从第三方包导入可能缺少全局配置和插件,建议改为:
-import dayjs from 'dayjs';
+import dayjs from '../util/dayjs';
以确保加载本地封装的 dayjs 实例及所有插件。
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
import dayjs from 'dayjs'; | |
-import dayjs from 'dayjs'; | |
+import dayjs from '../util/dayjs'; |
🤖 Prompt for AI Agents
In src/mixin/CalendarMixin.js at line 4, the import statement for dayjs directly
imports from the third-party package, which may miss global configurations and
plugins. Change the import path to point to the local wrapped dayjs instance
that includes all necessary plugins and configurations to ensure consistent
behavior across the project.
import Calendar from '@seafile/seafile-calendar/src'; | ||
import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
组件导入路径统一更新
Calendar 和 RangeCalendar 组件的导入路径已正确更新。建议验证新包是否已正确发布并可用。
验证新包的可用性:
🏁 Script executed:
#!/bin/bash
# 检查 package.json 中是否包含新的包依赖
cat package.json | jq '.dependencies["@seafile/seafile-calendar"]'
Length of output: 73
新增依赖缺失:请在 package.json 中添加 @seafile/seafile-calendar 依赖
当前在 examples/control-panel.js 第 5-6 行已统一更新组件导入路径:
import Calendar from '@seafile/seafile-calendar/src';
import RangeCalendar from '@seafile/seafile-calendar/src/RangeCalendar';
但经验证,package.json 的 dependencies 中并未包含该包。
请按以下步骤修复:
- 在 package.json 的
dependencies
中添加"@seafile/seafile-calendar": "⏤-版本号-⏤"
- 或运行命令安装并更新 package.json:
npm install @seafile/seafile-calendar --save
- 确认安装完成后在 CI/CD 或本地环境中重新构建并测试。
🤖 Prompt for AI Agents
In examples/control-panel.js at lines 5-6, the imports for Calendar and
RangeCalendar from '@seafile/seafile-calendar/src' are correct, but the package
'@seafile/seafile-calendar' is missing from package.json dependencies. To fix
this, add "@seafile/seafile-calendar" with the appropriate version to the
dependencies section of package.json or run 'npm install
@seafile/seafile-calendar --save' to add it automatically. After updating,
rebuild and test the project locally or in CI/CD to ensure the package is
properly installed and available.
@@ -38,7 +38,7 @@ | |||
|
|||
&:hover { | |||
cursor: pointer; | |||
color: #23c0fa; | |||
color: #f09f4g; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
修复无效的十六进制颜色代码
颜色值 #f09f4g
包含无效的十六进制字符 'g'。有效的十六进制颜色代码只能包含 0-9 和 a-f 字符。
应用此修复:
- color: #f09f4g;
+ color: #f09f3f;
🤖 Prompt for AI Agents
In assets/index/MonthPanel.less at line 41, the color value '#f09f4g' contains
an invalid hexadecimal character 'g'. Replace 'g' with a valid hexadecimal digit
(0-9 or a-f) to correct the color code.
&:hover { | ||
cursor: pointer; | ||
color: #23c0fa; | ||
color: #f09f4g; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
无效的十六进制颜色值
> a:hover
中使用的 color: #f09f4g
包含非法字符 g
,应修正为有效的十六进制值(例如 #f09f3f
)。
🤖 Prompt for AI Agents
In assets/index/DecadePanel.less around lines 35 to 38, the color value #f09f4g
used in the :hover selector is invalid due to the character 'g'. Replace this
with a valid hexadecimal color code, such as #f09f3f, to fix the syntax error.
it('up works', () => { | ||
const original = calendar.state().value; | ||
const expected = original.clone(); | ||
expected.add(-7, 'day'); | ||
let expected = original.clone(); | ||
expected = expected.add(-7, 'day'); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
测试用例不完整
这个 "up works" 测试用例缺少实际的测试逻辑。
补充缺失的测试逻辑:
it('up works', () => {
const original = calendar.state().value;
let expected = original.clone();
expected = expected.add(-7, 'day');
+ calendar.simulate('keyDown', { keyCode: keyCode.UP });
+ expect(calendar.state().value.date()).toBe(expected.date());
+ expect(input.getDOMNode().value).toBe('');
});
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
it('up works', () => { | |
const original = calendar.state().value; | |
const expected = original.clone(); | |
expected.add(-7, 'day'); | |
let expected = original.clone(); | |
expected = expected.add(-7, 'day'); | |
}); | |
it('up works', () => { | |
const original = calendar.state().value; | |
let expected = original.clone(); | |
expected = expected.add(-7, 'day'); | |
calendar.simulate('keyDown', { keyCode: keyCode.UP }); | |
expect(calendar.state().value.date()).toBe(expected.date()); | |
expect(input.getDOMNode().value).toBe(''); | |
}); |
🤖 Prompt for AI Agents
In tests/Calendar.spec.jsx around lines 224 to 228, the "up works" test case is
incomplete as it lacks assertions to verify the expected behavior. Complete the
test by adding logic that triggers the "up" action on the calendar component,
then assert that the calendar's state value has correctly moved up by 7 days
compared to the original state.
const firstDayName = typeof firstDayOfWeek === 'string' | ||
? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1) | ||
: 'Sunday'; | ||
const firstDayIndex = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0; | ||
const lastMonthDiffDay = (day + 7 - firstDayIndex) % 7; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
改进 firstDayOfWeek 的处理逻辑
当前实现有几个潜在问题:
- 当
DAY_NAME_TO_INDEX[firstDayName]
为undefined
时,会返回 0(Sunday),但这可能掩盖了配置错误 - 没有验证输入的有效性
建议改进错误处理:
-const firstDayName = typeof firstDayOfWeek === 'string'
- ? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1)
- : 'Sunday';
-const firstDayIndex = DAY_NAME_TO_INDEX[firstDayName] ? DAY_NAME_TO_INDEX[firstDayName] : 0;
+const firstDayName = typeof firstDayOfWeek === 'string'
+ ? firstDayOfWeek[0].toUpperCase() + firstDayOfWeek.slice(1)
+ : 'Sunday';
+const firstDayIndex = DAY_NAME_TO_INDEX[firstDayName];
+if (firstDayIndex === undefined) {
+ console.warn(`Invalid firstDayOfWeek: "${firstDayOfWeek}". Using default "Sunday".`);
+ firstDayIndex = 0;
+}
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In src/date/DateTBody.jsx around lines 80 to 84, improve the handling of
firstDayOfWeek by validating its value before use. Instead of defaulting
silently to 0 when DAY_NAME_TO_INDEX[firstDayName] is undefined, explicitly
check if firstDayName exists in DAY_NAME_TO_INDEX. If not, throw an error or
handle the invalid input case to avoid masking configuration errors. Also, add
validation to ensure firstDayOfWeek is a valid string matching expected day
names before processing.
componentDidMount() { | ||
const { defaultMinutesTime } = this.props; | ||
const showTimeIndex = this.times.findIndex(item => item >= defaultMinutesTime); | ||
const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex - 1 : 16; | ||
this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
建议提取魔法数字为常量
滚动计算中使用了硬编码的数字 34
,这似乎是每个时间项的高度。建议提取为常量以提高可维护性。
在组件顶部添加常量:
+const TIME_ITEM_HEIGHT = 34;
+
export default class CalendarRightPanel extends React.Component {
然后更新滚动计算:
- this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex);
+ this.timeRef.current.scrollTo(0, TIME_ITEM_HEIGHT * scrollTimeIndex);
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
componentDidMount() { | |
const { defaultMinutesTime } = this.props; | |
const showTimeIndex = this.times.findIndex(item => item >= defaultMinutesTime); | |
const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex - 1 : 16; | |
this.timeRef.current.scrollTo(0, 34 * scrollTimeIndex); | |
} | |
// at the top of the file | |
const TIME_ITEM_HEIGHT = 34; | |
export default class CalendarRightPanel extends React.Component { | |
componentDidMount() { | |
const { defaultMinutesTime } = this.props; | |
const showTimeIndex = this.times.findIndex(item => item >= defaultMinutesTime); | |
const scrollTimeIndex = showTimeIndex > -1 ? showTimeIndex - 1 : 16; | |
this.timeRef.current.scrollTo(0, TIME_ITEM_HEIGHT * scrollTimeIndex); | |
} | |
// …rest of the component | |
} |
🤖 Prompt for AI Agents
In src/calendar/CalendarRightPanel.jsx around lines 25 to 30, the scroll
calculation uses a hardcoded number 34 representing the height of each time
item. To improve maintainability, define this value as a constant at the top of
the component file, for example TIME_ITEM_HEIGHT = 34, and then replace the
hardcoded 34 in the scrollTo call with this constant.
const selectedDate = value.format().slice(0, 10); | ||
const highlight = this.state.highlightTime; | ||
const highlightTime = highlight ? highlight.format().slice(11, 16) : null; | ||
const isZhcn = (locale && locale.today === '今天'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
改进区域设置检测逻辑
通过检查 '今天' 字符串来判断是否为中文区域设置的方法不够可靠。建议使用更标准的方式。
- const isZhcn = (locale && locale.today === '今天');
+ const isZhcn = (locale && (locale.locale === 'zh-cn' || locale.lang === 'zh-cn'));
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
const isZhcn = (locale && locale.today === '今天'); | |
const isZhcn = (locale && (locale.locale === 'zh-cn' || locale.lang === 'zh-cn')); |
🤖 Prompt for AI Agents
In src/calendar/CalendarRightPanel.jsx at line 64, the current method of
detecting the Chinese locale by checking if locale.today equals '今天' is
unreliable. Replace this with a more standard approach, such as checking the
locale string or language code directly (e.g., using locale.startsWith('zh') or
a similar robust locale detection method) to accurately determine if the locale
is Chinese.
src/calendar/CalendarRightPanel.jsx
Outdated
{this.times.map((time) => { | ||
let current = dayjs(`${selectedDate} ${time}`); | ||
current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb'); | ||
return ( | ||
<li | ||
key={time} | ||
onClick={this.onSelect.bind(this, current)} | ||
className={`${highlightTime === time ? `${prefixCls}-selected-time` : ''}`} | ||
>{time}</li> | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
优化渲染性能
在 render 方法中使用 bind
会在每次渲染时创建新的函数实例,影响性能。
创建一个处理点击的方法:
+ handleTimeClick = (time) => {
+ const { value } = this.props;
+ const selectedDate = value.format().slice(0, 10);
+ const isZhcn = (this.props.locale && this.props.locale.locale === 'zh-cn');
+ let current = dayjs(`${selectedDate} ${time}`);
+ current = isZhcn ? current.locale('zh-cn') : current.locale('en-gb');
+ this.onSelect(current);
+ }
然后在 render 中使用:
- onClick={this.onSelect.bind(this, current)}
+ onClick={() => this.handleTimeClick(time)}
🤖 Prompt for AI Agents
In src/calendar/CalendarRightPanel.jsx around lines 72 to 81, the onClick
handler uses bind inside the render method, which creates a new function on
every render and hurts performance. To fix this, define a separate method that
takes the time parameter and handles the click, then pass that method directly
in the onClick without using bind. This avoids creating new function instances
during rendering and improves performance.
Summary by CodeRabbit
新功能
showHourAndMinute
和onClickRightPanelTime
属性说明。重构与依赖变更
@seafile/seafile-calendar
,依赖与元数据更新。样式更新
文档
测试
杂项