@voplus/morpho-workspace 11.2.3 → 11.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/Modules.js +2 -0
- package/es/Modules.js.map +1 -1
- package/es/data/worktype/metas.d.ts +12 -0
- package/es/data/worktype/metas.js +23 -0
- package/es/data/worktype/metas.js.map +1 -0
- package/es/modules/{calendar/CalendarRoutes.d.ts → calendar-board/CalendarBoardRoutes.d.ts} +2 -1
- package/es/modules/{calendar/CalendarRoutes.js → calendar-board/CalendarBoardRoutes.js} +10 -9
- package/es/modules/calendar-board/CalendarBoardRoutes.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarActionProperties/index.d.ts +20 -0
- package/es/modules/calendar-board/components/CalendarActionProperties/index.js +36 -0
- package/es/modules/calendar-board/components/CalendarActionProperties/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarBoardGrid/index.d.ts +45 -0
- package/es/modules/calendar-board/components/CalendarBoardGrid/index.js +89 -0
- package/es/modules/calendar-board/components/CalendarBoardGrid/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarEventChip/index.d.ts +22 -0
- package/es/modules/calendar-board/components/CalendarEventChip/index.js +20 -0
- package/es/modules/calendar-board/components/CalendarEventChip/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarLegend/index.d.ts +42 -0
- package/es/modules/calendar-board/components/CalendarLegend/index.js +94 -0
- package/es/modules/calendar-board/components/CalendarLegend/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarMoreLink/index.d.ts +11 -0
- package/es/modules/calendar-board/components/CalendarMoreLink/index.js +12 -0
- package/es/modules/calendar-board/components/CalendarMoreLink/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarSidebar/index.d.ts +34 -0
- package/es/modules/calendar-board/components/CalendarSidebar/index.js +45 -0
- package/es/modules/calendar-board/components/CalendarSidebar/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarToolbar/index.d.ts +30 -0
- package/es/modules/calendar-board/components/CalendarToolbar/index.js +30 -0
- package/es/modules/calendar-board/components/CalendarToolbar/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarUpcomingBar/index.d.ts +30 -0
- package/es/modules/calendar-board/components/CalendarUpcomingBar/index.js +35 -0
- package/es/modules/calendar-board/components/CalendarUpcomingBar/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarUpcomingEntry/index.d.ts +25 -0
- package/es/modules/calendar-board/components/CalendarUpcomingEntry/index.js +35 -0
- package/es/modules/calendar-board/components/CalendarUpcomingEntry/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarViewFilter/index.d.ts +19 -0
- package/es/modules/calendar-board/components/CalendarViewFilter/index.js +29 -0
- package/es/modules/calendar-board/components/CalendarViewFilter/index.js.map +1 -0
- package/es/modules/calendar-board/components/CalendarViewSwitcher/index.d.ts +14 -0
- package/es/modules/calendar-board/components/CalendarViewSwitcher/index.js +15 -0
- package/es/modules/calendar-board/components/CalendarViewSwitcher/index.js.map +1 -0
- package/es/modules/calendar-board/event-meta.d.ts +262 -0
- package/es/modules/calendar-board/event-meta.js +329 -0
- package/es/modules/calendar-board/event-meta.js.map +1 -0
- package/es/modules/calendar-board/layout.d.ts +27 -0
- package/es/modules/calendar-board/layout.js +20 -0
- package/es/modules/calendar-board/layout.js.map +1 -0
- package/es/modules/calendar-board/pages/CalendarBoard/index.css +262 -0
- package/es/modules/calendar-board/pages/CalendarBoard/index.d.ts +4 -0
- package/es/modules/calendar-board/pages/CalendarBoard/index.js +323 -0
- package/es/modules/calendar-board/pages/CalendarBoard/index.js.map +1 -0
- package/es/modules/calendar-board/pages/CalendarBoard/state.d.ts +112 -0
- package/es/modules/calendar-board/pages/CalendarBoard/state.js +206 -0
- package/es/modules/calendar-board/pages/CalendarBoard/state.js.map +1 -0
- package/es/modules/calendar-board/sidebar-data.d.ts +35 -0
- package/es/modules/calendar-board/sidebar-data.js +28 -0
- package/es/modules/calendar-board/sidebar-data.js.map +1 -0
- package/es/modules/meeting/components/NewMeetingForm/index.js +1 -1
- package/es/modules/meeting/components/NewMeetingForm/index.js.map +1 -1
- package/es/modules/project/ProjectDefaultView/index.js +2 -2
- package/es/modules/project/ProjectDefaultView/index.js.map +1 -1
- package/es/modules/work/work-schedule/components/WorkScheduleProperties/index.js +2 -3
- package/es/modules/work/work-schedule/components/WorkScheduleProperties/index.js.map +1 -1
- package/es/modules/work/work-type/components/WorkTypeLink/index.d.ts +7 -0
- package/es/modules/work/work-type/components/WorkTypeLink/index.js +16 -0
- package/es/modules/work/work-type/components/WorkTypeLink/index.js.map +1 -0
- package/es/modules/work/work-type/components/WorkTypeList/index.d.ts +5 -2
- package/es/modules/work/work-type/components/WorkTypeList/index.js +8 -6
- package/es/modules/work/work-type/components/WorkTypeList/index.js.map +1 -1
- package/es/routes.js +2 -2
- package/es/routes.js.map +1 -1
- package/package.json +1 -1
- package/es/modules/calendar/CalendarRoutes.js.map +0 -1
- package/es/modules/calendar/components/ActionCard/index.d.ts +0 -7
- package/es/modules/calendar/components/ActionCard/index.js +0 -12
- package/es/modules/calendar/components/ActionCard/index.js.map +0 -1
- package/es/modules/calendar/components/CalendarEventContent/index.d.ts +0 -11
- package/es/modules/calendar/components/CalendarEventContent/index.js +0 -10
- package/es/modules/calendar/components/CalendarEventContent/index.js.map +0 -1
- package/es/modules/calendar/components/CalendarMenu/index.css +0 -30
- package/es/modules/calendar/components/CalendarMenu/index.d.ts +0 -7
- package/es/modules/calendar/components/CalendarMenu/index.js +0 -52
- package/es/modules/calendar/components/CalendarMenu/index.js.map +0 -1
- package/es/modules/calendar/pages/CalendarMonth/index.css +0 -248
- package/es/modules/calendar/pages/CalendarMonth/index.d.ts +0 -4
- package/es/modules/calendar/pages/CalendarMonth/index.js +0 -190
- package/es/modules/calendar/pages/CalendarMonth/index.js.map +0 -1
- package/es/modules/calendar/pages/CalendarMonth/state.d.ts +0 -11
- package/es/modules/calendar/pages/CalendarMonth/state.js +0 -58
- package/es/modules/calendar/pages/CalendarMonth/state.js.map +0 -1
- package/es/modules/my-document/SectionTemplate/documentGroups.test.d.ts +0 -1
- package/es/modules/my-document/SectionTemplate/documentGroups.test.js +0 -63
- package/es/modules/my-document/SectionTemplate/documentGroups.test.js.map +0 -1
- package/es/modules/work/work-type/components/WorkTypeList/index.css +0 -5
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
2
|
+
import { observe, useRenderOnChange } from "@voplus/morpho-ui";
|
|
3
|
+
import { message } from "antd";
|
|
4
|
+
import { useOnDeleteDocument } from "@voplus/morpho-document-core";
|
|
5
|
+
import { useOnDeleteWorkSchedule } from "../../../../data/work-schedule/work-schedule-events";
|
|
6
|
+
import { FilterOptionsContext, FilterOptionsContextState } from "@voplus/morpho-ui/es/data";
|
|
7
|
+
import { useCalendarListEffect, useCalendarStore } from "../../../../data/calendar";
|
|
8
|
+
import NodePropertiesView from "@voplus/morpho-document-core/es/components/NodePropertiesView";
|
|
9
|
+
import { useDeepMemo, useTabItem } from "@voplus/morpho-data";
|
|
10
|
+
import AsideContent from "@voplus/morpho-ui/es/components/layout/AsideContent";
|
|
11
|
+
import { runInAction } from "mobx";
|
|
12
|
+
import dayjs from "dayjs";
|
|
13
|
+
import { ConfigProvider } from "antd";
|
|
14
|
+
import antdTheme from "@voplus/morpho-theme/antdTheme";
|
|
15
|
+
import FilterView from "@voplus/morpho-ui/es/controls/FilterView";
|
|
16
|
+
import EventsFilter from "../../../../controls/filters/EventsFilter";
|
|
17
|
+
import { applyDropToEvents, buildDropPayload, findEventById, isActionSource, toPropertiesTarget, } from "../../event-meta";
|
|
18
|
+
import CalendarToolbar from "../../components/CalendarToolbar";
|
|
19
|
+
import CalendarLegend from "../../components/CalendarLegend";
|
|
20
|
+
import CalendarBoardGrid from "../../components/CalendarBoardGrid";
|
|
21
|
+
import CalendarSidebar from "../../components/CalendarSidebar";
|
|
22
|
+
import CalendarViewSwitcher from "../../components/CalendarViewSwitcher";
|
|
23
|
+
import CalendarViewFilter from "../../components/CalendarViewFilter";
|
|
24
|
+
import CalendarUpcomingEntry from "../../components/CalendarUpcomingEntry";
|
|
25
|
+
import CalendarActionProperties from "../../components/CalendarActionProperties";
|
|
26
|
+
import { resolveBoardLayout } from "../../layout";
|
|
27
|
+
import { SMALL_SCREEN_QUERY, useMediaQuery } from "../../../my-document/useMediaQuery";
|
|
28
|
+
import { FULL_CALENDAR_VIEW, State } from "./state";
|
|
29
|
+
import "./index.css";
|
|
30
|
+
const CalendarBoard = () => {
|
|
31
|
+
const tab = useTabItem();
|
|
32
|
+
const filterState = useDeepMemo(() => new FilterOptionsContextState({
|
|
33
|
+
defaults: {
|
|
34
|
+
filters: [{ c: "OwnerType", o: "contains", v1: JSON.stringify(["My"]), l: "And" }],
|
|
35
|
+
page: { Page: 1, PageSize: 200 },
|
|
36
|
+
},
|
|
37
|
+
}), []);
|
|
38
|
+
const [state] = useState(new State());
|
|
39
|
+
const [currentTime, setCurrentTime] = useState();
|
|
40
|
+
const [calendarApi, setCalendarApi] = useState();
|
|
41
|
+
/**
|
|
42
|
+
* 小屏判定(< 1024px)。
|
|
43
|
+
*
|
|
44
|
+
* 与 my-document 的列表页同一份 hook 与断点常量,判定结果交给 resolveBoardLayout
|
|
45
|
+
* 统一分派(底部条 / 视图切换位置 / 侧栏),这里不直接写分支。
|
|
46
|
+
*
|
|
47
|
+
* 必须在组件体里调用(不能挪进 observe):observe 在 <Observer> 的 render 里执行 children,
|
|
48
|
+
* 在里面调 hook 会挂到 Observer 自己的 hook 状态上。它是个普通布尔值,
|
|
49
|
+
* 变化时会触发本组件重渲染,observe 随之重跑。
|
|
50
|
+
*/
|
|
51
|
+
const isSmallScreen = useMediaQuery(SMALL_SCREEN_QUERY);
|
|
52
|
+
/**
|
|
53
|
+
* 页面内右侧属性面板的上下文。
|
|
54
|
+
*
|
|
55
|
+
* 与列表页(NotificationList / TaskTabView)同一套姿势:页面自己 createContext,
|
|
56
|
+
* 交给 <AsideContent> 渲染,点条目时用 openAside 把内容塞进去。
|
|
57
|
+
*/
|
|
58
|
+
const [asideContext] = useState(AsideContent.createContext());
|
|
59
|
+
const calendarRef = useRef(null);
|
|
60
|
+
const calendar = useCalendarStore();
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
runInAction(() => (tab.title = "Calendar"));
|
|
63
|
+
}, []);
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setCalendarApi(calendarRef?.current?.getApi());
|
|
66
|
+
}, [calendarRef]);
|
|
67
|
+
useOnDeleteDocument((s, doc) => {
|
|
68
|
+
state.listOptions = state.listOptions.filter((i) => i.source?.id !== doc.id);
|
|
69
|
+
});
|
|
70
|
+
useOnDeleteWorkSchedule((s, doc) => {
|
|
71
|
+
state.listOptions = state.listOptions.filter((i) => i.source?.id !== doc.id);
|
|
72
|
+
});
|
|
73
|
+
useRenderOnChange(() => filterState.options);
|
|
74
|
+
/**
|
|
75
|
+
* 本地拖拽落点,按事件 id 记录;以及给它们编号的单调递增版本号。
|
|
76
|
+
*
|
|
77
|
+
* 存在的理由:列表请求与拖拽保存是两个独立在飞的请求,谁先到谁后到没有保证。
|
|
78
|
+
* 一次「在拖拽之前就已发出」的列表请求,其响应里必然还是旧日期,而列表回调原先
|
|
79
|
+
* 直接整体替换 listOptions —— 刚拖出去的卡片会被打回原位。更糟的是它不会自愈:
|
|
80
|
+
* CalendarStore.edit 只写 items,从不回写 listOptions,所以此后 UI 会一直停在旧日期,
|
|
81
|
+
* 与服务端不一致。
|
|
82
|
+
*
|
|
83
|
+
* 光看 `pending` 不够:响应完全可能晚到保存结束之后(那时 pending 已是 false),
|
|
84
|
+
* 而它取到的数据依然早于这次改动。所以再记一个 `revision`,配合 listRevision 判断
|
|
85
|
+
* 「这份响应到底知不知道我拖过」。
|
|
86
|
+
*/
|
|
87
|
+
const drops = useRef(new Map());
|
|
88
|
+
const dropRevision = useRef(0);
|
|
89
|
+
/**
|
|
90
|
+
* 本次列表加载**登记**时的版本号。
|
|
91
|
+
*
|
|
92
|
+
* useCalendarListEffect 只在 filterState.options 深度变化时重新登记,而请求正是
|
|
93
|
+
* 在登记那一刻发出的(loader 在同一个 effect 体里被调用)—— 所以在组件体里取
|
|
94
|
+
* 当前值就等于「本次请求发出时已有的拖拽版本」。闭包随登记它的那次渲染固定下来,
|
|
95
|
+
* 正是这里需要的语义。
|
|
96
|
+
*/
|
|
97
|
+
const listRevision = dropRevision.current;
|
|
98
|
+
/**
|
|
99
|
+
* 把一条服务端事件与本地拖拽记录对账。
|
|
100
|
+
*
|
|
101
|
+
* 本地落点尚未被服务端确认时以本地为准;已确认则采用服务端日期,并把记录同步过去 ——
|
|
102
|
+
* 少了后半句,被拖过的事件就再也接不住别处对它的改动(本地覆盖会变成永久的)。
|
|
103
|
+
*/
|
|
104
|
+
const withLocalDrop = (item) => {
|
|
105
|
+
const dropped = drops.current.get(String(item.id));
|
|
106
|
+
if (!dropped)
|
|
107
|
+
return item;
|
|
108
|
+
if (dropped.start && (dropped.pending || dropped.revision > listRevision)) {
|
|
109
|
+
const patched = {
|
|
110
|
+
...item,
|
|
111
|
+
start: dropped.start,
|
|
112
|
+
startDate: dayjs(dropped.start).toDate(),
|
|
113
|
+
};
|
|
114
|
+
// 与 applyDropToEvents 同一套写法:end 拿不到时保留服务端的值,不写成 null
|
|
115
|
+
if (dropped.end)
|
|
116
|
+
patched.end = dropped.end;
|
|
117
|
+
return patched;
|
|
118
|
+
}
|
|
119
|
+
// 服务端已包含这次改动:记录跟着刷新,下次判断才有正确的前值
|
|
120
|
+
dropped.start = item.start;
|
|
121
|
+
dropped.end = item.end;
|
|
122
|
+
return item;
|
|
123
|
+
};
|
|
124
|
+
useCalendarListEffect(null, (list) => {
|
|
125
|
+
runInAction(() => {
|
|
126
|
+
const events = list;
|
|
127
|
+
state.listOptions = events.map((item) => {
|
|
128
|
+
// 事件卡颜色改由 CHIP_COLOR_CLASS 按 source.type 着色(见 event-meta.ts),
|
|
129
|
+
// 这里只补齐 source.title,其余沿用 CalendarMonth 的写法
|
|
130
|
+
if (item.source)
|
|
131
|
+
item.source.title = item.title;
|
|
132
|
+
return withLocalDrop(item);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
}, filterState.options);
|
|
136
|
+
/**
|
|
137
|
+
* 点击事件卡 / 侧栏条目 / 图例浮层条目 → 在右侧 aside 打开 PropertiesView。
|
|
138
|
+
*
|
|
139
|
+
* 两种事件源,两条路:
|
|
140
|
+
* - Action 不是文档节点(它的 meta 在 ActionMetaStore,不在 DocumentMetaStore),
|
|
141
|
+
* 走 <CalendarActionProperties>,自己调 action 的加载入口 —— 见该组件的注释;
|
|
142
|
+
* - 其余把事件的 source 交给 <NodePropertiesView>:它按 type 派发到对应 meta 的
|
|
143
|
+
* getPropertiesView(Task / WorkSchedule / Meeting … 各有自己的属性视图,
|
|
144
|
+
* 未注册的 type 落到通用文档属性视图)。
|
|
145
|
+
*
|
|
146
|
+
* 两条路都带 key=source.id:换一条事件要重挂,否则上一条的加载错误会留在面板上。
|
|
147
|
+
*
|
|
148
|
+
* source 到 node 的形状收窄见 event-meta 的 toPropertiesTarget。
|
|
149
|
+
*/
|
|
150
|
+
const openSource = (source) => {
|
|
151
|
+
if (!source?.id)
|
|
152
|
+
return;
|
|
153
|
+
asideContext.openAside(isActionSource(source) ? (React.createElement(CalendarActionProperties, { key: source.id, id: source.id })) : (React.createElement(NodePropertiesView, { key: source.id, node: toPropertiesTarget(source) })), { span: 9 });
|
|
154
|
+
};
|
|
155
|
+
/** 切换 month / week / day 视图 */
|
|
156
|
+
const handleChangeType = (value) => {
|
|
157
|
+
runInAction(() => (state.type = value));
|
|
158
|
+
calendarApi?.changeView(FULL_CALENDAR_VIEW[value]);
|
|
159
|
+
};
|
|
160
|
+
/** 日期发生变化的回调 */
|
|
161
|
+
const onChange = (date, dateString) => {
|
|
162
|
+
const dateText = Array.isArray(dateString) ? dateString[0] : dateString;
|
|
163
|
+
setCurrentTime(date);
|
|
164
|
+
if (state.type === "week") {
|
|
165
|
+
calendarApi?.gotoDate(`${dayjs(date).format("YYYY-MM-DD")}`);
|
|
166
|
+
}
|
|
167
|
+
else if (dateText) {
|
|
168
|
+
calendarApi?.gotoDate(dateText);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
/**
|
|
172
|
+
* 当拖动停止并且事件已移至其他日期/时间时触发。
|
|
173
|
+
*
|
|
174
|
+
* 四件事都和「拖完跳回原位 / 刷新后位置不对」有关,逐条说明:
|
|
175
|
+
*
|
|
176
|
+
* 1. 时间格式:交给 buildDropPayload 写成**本地时间**的 `YYYY-MM-DDTHH:mm:ss.SSS`,
|
|
177
|
+
* 而不是 toISOString()(UTC 时刻,UTC+8 下拖到某天零点时日期会退回前一天,
|
|
178
|
+
* 服务端按本地时间解析就落到错误日期)。
|
|
179
|
+
* 2. **先乐观写回本地模型再发请求**:请求往返期间只要有任意一次重渲染,事件源就可能
|
|
180
|
+
* 被重置,本地数据若还停在旧位置,刚拖过去的卡片会立刻被打回原位 —— 这就是
|
|
181
|
+
* 「拖拽当时跳回原位」的直接原因。
|
|
182
|
+
* 3. 失败要可见并回退:原先用 `error: "message"`,Store.action 会吞掉异常只弹个 toast,
|
|
183
|
+
* 事件仍停在拖过去的位置、看着像保存成功。改成回调显式判断,
|
|
184
|
+
* 失败就把本地模型与卡片一起退回拖拽前(changelog 的既有约定:
|
|
185
|
+
* 「改进edit处理,错误时UI重设回原值」)。
|
|
186
|
+
* 4. 事件源引用稳定:见 state.ts 的 sidebarData 与 CalendarBoardGrid 里的 useMemo。
|
|
187
|
+
*/
|
|
188
|
+
const eventDrop = async (info) => {
|
|
189
|
+
const id = info.event.id;
|
|
190
|
+
/*
|
|
191
|
+
* 拒绝这次拖拽的三种情况都退回,但各自留下可诊断的线索 ——
|
|
192
|
+
* 静默 revert 的后果就是用户只看到「拖完立刻跳回」,却无从知道为什么。
|
|
193
|
+
*/
|
|
194
|
+
if (!info.event.extendedProps.allowChangeStart) {
|
|
195
|
+
// 服务端没给改期权限(或压根没下发这个字段):这是设计如此,直接退回
|
|
196
|
+
console.warn("[CalendarBoard] 该事件不允许改期,已退回", {
|
|
197
|
+
id,
|
|
198
|
+
allowChangeStart: info.event.extendedProps.allowChangeStart,
|
|
199
|
+
extendedProps: Object.keys(info.event.extendedProps ?? {}),
|
|
200
|
+
});
|
|
201
|
+
info.revert();
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
if (!id) {
|
|
205
|
+
// FullCalendar 对没有 id 的事件给的是空字符串,此时无从定位服务端记录
|
|
206
|
+
console.warn("[CalendarBoard] 事件没有 id,无法保存改期结果", {
|
|
207
|
+
title: info.event.title,
|
|
208
|
+
extendedProps: Object.keys(info.event.extendedProps ?? {}),
|
|
209
|
+
});
|
|
210
|
+
info.revert();
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const drop = { start: info.event.start, end: info.event.end };
|
|
214
|
+
const payload = buildDropPayload(drop);
|
|
215
|
+
if (!payload) {
|
|
216
|
+
console.warn("[CalendarBoard] 拿不到有效的落点时间,已退回", {
|
|
217
|
+
id,
|
|
218
|
+
start: info.event.start,
|
|
219
|
+
end: info.event.end,
|
|
220
|
+
});
|
|
221
|
+
info.revert();
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
/*
|
|
225
|
+
* 同一条事件上一次改期还没保存完:直接退回,不排队。
|
|
226
|
+
*
|
|
227
|
+
* 放行会让两次 edit 同时在飞,而完成顺序不可控 —— 服务端最后写入的未必是用户
|
|
228
|
+
* 最后拖的那次,UI 却停在最后一次拖拽上,两边日期就此不一致;若先落的那次失败,
|
|
229
|
+
* 它的回退快照还是「第一次拖拽之前」的日期,会把后一次已成功的改动一起抹掉,
|
|
230
|
+
* 把卡片留在一个从未保存成功的日期上。
|
|
231
|
+
*
|
|
232
|
+
* 退回是看得见的反馈(卡片弹回),好过静默写坏日期。守卫按事件记,
|
|
233
|
+
* 不同事件之间互不阻塞。
|
|
234
|
+
*/
|
|
235
|
+
if (drops.current.get(id)?.pending) {
|
|
236
|
+
console.warn("[CalendarBoard] 该事件上一次改期还在保存,本次拖拽已退回", { id });
|
|
237
|
+
info.revert();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// 回退用的快照要从列表里取:info.oldEvent 不保证存在,
|
|
241
|
+
// 拿不到时回退会静默失效 —— 模型留在新位置、卡片却退回原位,两边不一致
|
|
242
|
+
const before = findEventById(state.listOptions, id);
|
|
243
|
+
const rollback = { start: before?.start ?? before?.startDate, end: before?.end };
|
|
244
|
+
// 先登记再乐观写回:登记必须早于请求发出,否则迟到的列表响应无从判断自己是否已过期
|
|
245
|
+
const change = {
|
|
246
|
+
start: drop.start,
|
|
247
|
+
end: drop.end,
|
|
248
|
+
revision: ++dropRevision.current,
|
|
249
|
+
pending: true,
|
|
250
|
+
};
|
|
251
|
+
drops.current.set(id, change);
|
|
252
|
+
runInAction(() => {
|
|
253
|
+
state.listOptions = applyDropToEvents(state.listOptions, id, drop);
|
|
254
|
+
});
|
|
255
|
+
let failed = false;
|
|
256
|
+
await calendar.edit(id, {
|
|
257
|
+
data: payload,
|
|
258
|
+
error: (error) => {
|
|
259
|
+
failed = true;
|
|
260
|
+
message.error(error.message);
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
if (failed) {
|
|
264
|
+
// 落点也要跟着回退:否则之后迟到的列表响应会拿这个已被放弃的日期
|
|
265
|
+
// 覆盖掉服务端的真实日期,等于把一次失败的拖拽复活
|
|
266
|
+
change.start = rollback.start;
|
|
267
|
+
change.end = rollback.end;
|
|
268
|
+
runInAction(() => {
|
|
269
|
+
state.listOptions = applyDropToEvents(state.listOptions, id, rollback);
|
|
270
|
+
});
|
|
271
|
+
info.revert();
|
|
272
|
+
}
|
|
273
|
+
/*
|
|
274
|
+
* 保存结束后再抬一次版本号:此后新登记的列表请求才会被认作「知道这次改动」,
|
|
275
|
+
* 重新以服务端为准(见 withLocalDrop)。pending 也要清掉,
|
|
276
|
+
* 否则这条事件再也拖不动第二次。
|
|
277
|
+
*/
|
|
278
|
+
change.pending = false;
|
|
279
|
+
change.revision = ++dropRevision.current;
|
|
280
|
+
};
|
|
281
|
+
return observe(() => {
|
|
282
|
+
/**
|
|
283
|
+
* 侧栏、图例、事件卡的推导(纯前端,见 sidebar-data.ts)。
|
|
284
|
+
*
|
|
285
|
+
* 取的是 state 上的 computed:既保证响应式(observe 是 <Observer>,只追踪它这次
|
|
286
|
+
* 渲染读到的 observable),又保证引用稳定 —— 详见 state.ts 里 sidebarData 的注释。
|
|
287
|
+
*/
|
|
288
|
+
const sidebar = state.sidebarData;
|
|
289
|
+
/**
|
|
290
|
+
* 三个响应式分支的唯一来源(规则本身见 layout.ts,那里有测试):
|
|
291
|
+
* - 小屏:不渲染右侧栏,Upcoming 走底部条 + Modal,视图切换收进 Filter;
|
|
292
|
+
* - 桌面:右侧属性面板展开时,Upcoming 面板不显示。
|
|
293
|
+
*
|
|
294
|
+
* asideContent 必须在 observe 内读 —— 属性面板一开一关要能让这里重新分派。
|
|
295
|
+
*/
|
|
296
|
+
const layout = resolveBoardLayout({
|
|
297
|
+
isSmallScreen,
|
|
298
|
+
isAsideOpen: !!asideContext.asideContent,
|
|
299
|
+
});
|
|
300
|
+
return (React.createElement(ConfigProvider, { theme: antdTheme },
|
|
301
|
+
React.createElement(AsideContent, { context: asideContext, className: "h-full w-full" },
|
|
302
|
+
React.createElement("div", { className: "calendar-board flex h-full w-full flex-col overflow-hidden text-sm" },
|
|
303
|
+
React.createElement(CalendarToolbar, { type: state.type, title: state.title, currentTime: currentTime, onToday: () => calendarApi?.today(), onPrev: () => calendarApi?.prev(), onNext: () => calendarApi?.next(), onChangeDate: onChange },
|
|
304
|
+
React.createElement(FilterOptionsContext.Provider, { value: filterState },
|
|
305
|
+
React.createElement(FilterView, { columns: [
|
|
306
|
+
React.createElement(EventsFilter, { key: "EventsFilter", defaultValue: ["My"] }),
|
|
307
|
+
// 小屏把视图切换收进 Filter 浮层(data 与工具栏那份同一处)
|
|
308
|
+
...(layout.viewSwitcherInFilter
|
|
309
|
+
? [
|
|
310
|
+
React.createElement(CalendarViewFilter, { key: "CalendarViewFilter", type: state.type, onChangeType: handleChangeType }),
|
|
311
|
+
]
|
|
312
|
+
: []),
|
|
313
|
+
] })),
|
|
314
|
+
!layout.viewSwitcherInFilter && (React.createElement(CalendarViewSwitcher, { type: state.type, onChangeType: handleChangeType }))),
|
|
315
|
+
React.createElement(CalendarLegend, { categories: sidebar.summary.categories, onSelectEvent: openSource }),
|
|
316
|
+
React.createElement("div", { className: "flex flex-1 min-h-0 overflow-hidden" },
|
|
317
|
+
React.createElement(CalendarBoardGrid, { events: sidebar.visibleEvents, initialView: state.type, colorMap: sidebar.summary.colorMap, calendarRef: calendarRef, onSelectEvent: openSource, onEventDrop: eventDrop, onDatesSet: (info) => state.datesRender(info) }),
|
|
318
|
+
layout.showSidebar && (React.createElement(CalendarSidebar, { upcoming: sidebar.upcoming, search: state.search, tab: state.sidebarTab, onSearch: state.setSearch, onChangeTab: state.setSidebarTab, onSelectEvent: openSource }))),
|
|
319
|
+
layout.showUpcomingBar && (React.createElement(CalendarUpcomingEntry, { total: sidebar.upcomingTotal, upcoming: sidebar.upcoming, search: state.search, tab: state.sidebarTab, onSearch: state.setSearch, onChangeTab: state.setSidebarTab, onSelectEvent: openSource }))))));
|
|
320
|
+
});
|
|
321
|
+
};
|
|
322
|
+
export default CalendarBoard;
|
|
323
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/modules/calendar-board/pages/CalendarBoard/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import type { CalendarBoardEvent } from "../../event-meta";
|
|
2
|
+
import { type ISidebarData } from "../../sidebar-data";
|
|
3
|
+
/** 设计稿工具栏的三个视图 */
|
|
4
|
+
export type CalendarViewType = "month" | "week" | "day";
|
|
5
|
+
/**
|
|
6
|
+
* 视图类型 → FullCalendar 视图名。
|
|
7
|
+
*
|
|
8
|
+
* - month → dayGridMonth(月格子,对应 calendar-recreation.html)
|
|
9
|
+
* - week → dayGridWeek(按天堆叠事件卡、无时间轴,对应 calendar-week-view.html)
|
|
10
|
+
* - day → timeGridDay(时间轴,对应 calendar-day-view.html)
|
|
11
|
+
*
|
|
12
|
+
* 三个视图全部由已安装的 daygrid / timegrid 插件提供,未引入新插件。
|
|
13
|
+
*/
|
|
14
|
+
export declare const FULL_CALENDAR_VIEW: Record<CalendarViewType, string>;
|
|
15
|
+
/**
|
|
16
|
+
* 上班时段:Day 视图只显示这一段,不再铺满 24 小时。
|
|
17
|
+
*
|
|
18
|
+
* slotMaxTime 是**开区间**,所以 09:00–18:00 的最后一格正好是 17:00–18:00。
|
|
19
|
+
* 这两个值目前只用在 timeGridDay;将来若把周视图换成 timeGridWeek,
|
|
20
|
+
* 直接复用即可。
|
|
21
|
+
*/
|
|
22
|
+
export declare const WORKDAY_START_TIME = "09:00:00";
|
|
23
|
+
export declare const WORKDAY_END_TIME = "18:00:00";
|
|
24
|
+
/**
|
|
25
|
+
* 周视图单列最多显示几条事件,其余收进 +N。
|
|
26
|
+
*
|
|
27
|
+
* 月视图每格只有一两行的空间(全局 DAY_MAX_EVENTS = 2),周视图则是一整列、
|
|
28
|
+
* 稿子里单列排了 5 张卡,所以单独给一个宽松的上限,不跟着月视图一起收紧。
|
|
29
|
+
*/
|
|
30
|
+
export declare const WEEK_MAX_EVENTS = 15;
|
|
31
|
+
/**
|
|
32
|
+
* FullCalendar 的按视图覆盖选项。
|
|
33
|
+
*
|
|
34
|
+
* dayGridWeek 要还原 calendar-week-view.html:表头只留 SUN..SAT、日期标签落在格子里。
|
|
35
|
+
* 收起的口径与月视图不同:不受行数上限约束(dayMaxEventRows: false,同时也让它
|
|
36
|
+
* 不跟着全局的 DAY_MAX_EVENTS 一起收紧),只按 WEEK_MAX_EVENTS 这个事件数上限收起。
|
|
37
|
+
*
|
|
38
|
+
* timeGridDay 只保留上班时段(见 WORKDAY_START_TIME):
|
|
39
|
+
* - slotMinTime / slotMaxTime 裁掉时段外的行;
|
|
40
|
+
* - scrollTime 让初始滚动停在 9:00(默认值是 06:00,裁掉后已经越界);
|
|
41
|
+
* - expandRows 让这 9 小时撑满可用高度,否则默认 30 分钟格高 1.5em,
|
|
42
|
+
* 9 小时只有约 320px,高面板下方会留一大片空白。
|
|
43
|
+
*/
|
|
44
|
+
export declare const FULL_CALENDAR_VIEW_OPTIONS: {
|
|
45
|
+
dayGridWeek: {
|
|
46
|
+
/** 不设行数上限(默认也是 false,这里写出来是为了不被外面的全局配置影响) */
|
|
47
|
+
dayMaxEventRows: boolean;
|
|
48
|
+
dayMaxEvents: number;
|
|
49
|
+
dayHeaderFormat: {
|
|
50
|
+
weekday: string;
|
|
51
|
+
};
|
|
52
|
+
dayCellContent: (arg: any) => string;
|
|
53
|
+
};
|
|
54
|
+
timeGridDay: {
|
|
55
|
+
slotMinTime: string;
|
|
56
|
+
slotMaxTime: string;
|
|
57
|
+
scrollTime: string;
|
|
58
|
+
expandRows: boolean;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* 工具栏 MONTH / WEEK / DAY 按钮,也是小屏 Filter 浮层里 By View 一列的 data。
|
|
63
|
+
*
|
|
64
|
+
* 两处文案口径不同,所以各留一个字段:
|
|
65
|
+
* - `label`:大写,工具栏分段控件的既有样式(稿子里的 MONTH / WEEK / DAY 胶囊);
|
|
66
|
+
* - `name`:Title Case,Filter 浮层里的复选框文案,与 By Events 的 "My Events" 同风格。
|
|
67
|
+
*/
|
|
68
|
+
export declare const VIEW_TYPE_OPTIONS: {
|
|
69
|
+
value: CalendarViewType;
|
|
70
|
+
label: string;
|
|
71
|
+
name: string;
|
|
72
|
+
}[];
|
|
73
|
+
/** 侧栏页签 */
|
|
74
|
+
export type CalendarSidebarTab = "upcoming" | "activity";
|
|
75
|
+
export declare class State {
|
|
76
|
+
accessor listOptions: CalendarBoardEvent[];
|
|
77
|
+
/** 当前视图类型 */
|
|
78
|
+
accessor type: CalendarViewType;
|
|
79
|
+
/** FullCalendar 头部日期(由 datesSet 同步) */
|
|
80
|
+
accessor title: string;
|
|
81
|
+
/** 侧栏搜索关键字(纯前端过滤,不触发重新请求) */
|
|
82
|
+
accessor search: string;
|
|
83
|
+
/** 被隐藏的事件分类(source.type) */
|
|
84
|
+
accessor hiddenTypes: Set<string>;
|
|
85
|
+
/** 侧栏页签 */
|
|
86
|
+
accessor sidebarTab: CalendarSidebarTab;
|
|
87
|
+
/** 呈现一组新日期时触发。 */
|
|
88
|
+
datesRender(info: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* 切换某个分类的显示 / 隐藏。
|
|
91
|
+
*
|
|
92
|
+
* 下面三个 action 写成箭头属性:它们会被直接当作 props 传给侧栏,
|
|
93
|
+
* 方法体里用到 this,脱离实例调用会抛
|
|
94
|
+
* `Cannot set properties of undefined`(MobX 的 action 用调用时的 this 作为 scope)。
|
|
95
|
+
*/
|
|
96
|
+
toggleType: (type: string) => void;
|
|
97
|
+
setSearch: (value: string) => void;
|
|
98
|
+
setSidebarTab: (tab: CalendarSidebarTab) => void;
|
|
99
|
+
/**
|
|
100
|
+
* 侧栏 / 图例 / 网格共用的推导结果。
|
|
101
|
+
*
|
|
102
|
+
* 用 computed 而不是每次渲染现算,关键是为了**引用稳定**:其中的 visibleEvents 会交给
|
|
103
|
+
* FullCalendar 当 eventSources,而每次渲染都换一个新数组会让 FullCalendar 重置事件源,
|
|
104
|
+
* 用它手上的外部数据覆盖内部状态 —— 刚拖拽出来的位置就会被打回原位。
|
|
105
|
+
* 依赖(listOptions / search / hiddenTypes)不变时,这里返回同一个对象。
|
|
106
|
+
*
|
|
107
|
+
* ⚠️ computed 只在**被观察时**才缓存,所以这个 getter 必须在 observe()(即
|
|
108
|
+
* mobx-react-lite 的 <Observer>)内部读 —— 挪到组件体里就会退化成每次现算,
|
|
109
|
+
* 引用不再稳定,拖拽结果又会被打回原位。测试里用 autorun 复刻了这个前提。
|
|
110
|
+
*/
|
|
111
|
+
get sidebarData(): ISidebarData;
|
|
112
|
+
}
|