@voplus/morpho-workspace 11.0.4 → 11.2.0

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.
Files changed (52) hide show
  1. package/es/controls/AssignButton/index.js +1 -5
  2. package/es/controls/AssignButton/index.js.map +1 -1
  3. package/es/modules/calendar/pages/CalendarMonth/index.d.ts +1 -0
  4. package/es/modules/calendar/pages/CalendarMonth/index.js +15 -1
  5. package/es/modules/calendar/pages/CalendarMonth/index.js.map +1 -1
  6. package/es/modules/calendar-board/CalendarBoardRoutes.d.ts +12 -0
  7. package/es/modules/calendar-board/CalendarBoardRoutes.js +28 -0
  8. package/es/modules/calendar-board/CalendarBoardRoutes.js.map +1 -0
  9. package/es/modules/calendar-board/components/CalendarBoardGrid/index.d.ts +45 -0
  10. package/es/modules/calendar-board/components/CalendarBoardGrid/index.js +48 -0
  11. package/es/modules/calendar-board/components/CalendarBoardGrid/index.js.map +1 -0
  12. package/es/modules/calendar-board/components/CalendarEventChip/index.d.ts +22 -0
  13. package/es/modules/calendar-board/components/CalendarEventChip/index.js +20 -0
  14. package/es/modules/calendar-board/components/CalendarEventChip/index.js.map +1 -0
  15. package/es/modules/calendar-board/components/CalendarLegend/index.d.ts +37 -0
  16. package/es/modules/calendar-board/components/CalendarLegend/index.js +81 -0
  17. package/es/modules/calendar-board/components/CalendarLegend/index.js.map +1 -0
  18. package/es/modules/calendar-board/components/CalendarMoreLink/index.d.ts +11 -0
  19. package/es/modules/calendar-board/components/CalendarMoreLink/index.js +12 -0
  20. package/es/modules/calendar-board/components/CalendarMoreLink/index.js.map +1 -0
  21. package/es/modules/calendar-board/components/CalendarSidebar/index.d.ts +27 -0
  22. package/es/modules/calendar-board/components/CalendarSidebar/index.js +43 -0
  23. package/es/modules/calendar-board/components/CalendarSidebar/index.js.map +1 -0
  24. package/es/modules/calendar-board/components/CalendarToolbar/index.d.ts +23 -0
  25. package/es/modules/calendar-board/components/CalendarToolbar/index.js +28 -0
  26. package/es/modules/calendar-board/components/CalendarToolbar/index.js.map +1 -0
  27. package/es/modules/calendar-board/event-meta.d.ts +160 -0
  28. package/es/modules/calendar-board/event-meta.js +209 -0
  29. package/es/modules/calendar-board/event-meta.js.map +1 -0
  30. package/es/modules/calendar-board/pages/CalendarBoard/index.css +262 -0
  31. package/es/modules/calendar-board/pages/CalendarBoard/index.d.ts +4 -0
  32. package/es/modules/calendar-board/pages/CalendarBoard/index.js +181 -0
  33. package/es/modules/calendar-board/pages/CalendarBoard/index.js.map +1 -0
  34. package/es/modules/calendar-board/pages/CalendarBoard/state.d.ts +116 -0
  35. package/es/modules/calendar-board/pages/CalendarBoard/state.js +232 -0
  36. package/es/modules/calendar-board/pages/CalendarBoard/state.js.map +1 -0
  37. package/es/modules/calendar-board/sidebar-data.d.ts +27 -0
  38. package/es/modules/calendar-board/sidebar-data.js +19 -0
  39. package/es/modules/calendar-board/sidebar-data.js.map +1 -0
  40. package/es/modules/tasks/components/SubTaskList/index.js +1 -4
  41. package/es/modules/tasks/components/SubTaskList/index.js.map +1 -1
  42. package/es/modules/tasks/controls/TaskStatusDataIcon/index.js +1 -7
  43. package/es/modules/tasks/controls/TaskStatusDataIcon/index.js.map +1 -1
  44. package/es/modules/work/components/WorksProperties/index.js +1 -8
  45. package/es/modules/work/components/WorksProperties/index.js.map +1 -1
  46. package/es/modules/work/controls/WorkStatusDataIcon/index.js +1 -7
  47. package/es/modules/work/controls/WorkStatusDataIcon/index.js.map +1 -1
  48. package/es/obsolete/space/components/Tasks/index.js +1 -2
  49. package/es/obsolete/space/components/Tasks/index.js.map +1 -1
  50. package/es/routes.js +2 -2
  51. package/es/routes.js.map +1 -1
  52. package/package.json +7 -5
@@ -0,0 +1,181 @@
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 QuickView from "@voplus/morpho-document-core/es/components/QuickView";
9
+ import { useDeepMemo, useTabItem } from "@voplus/morpho-data";
10
+ import { runInAction } from "mobx";
11
+ import dayjs from "dayjs";
12
+ import { ConfigProvider } from "antd";
13
+ import antdTheme from "@voplus/morpho-theme/antdTheme";
14
+ import FilterView from "@voplus/morpho-ui/es/controls/FilterView";
15
+ import EventsFilter from "../../../../controls/filters/EventsFilter";
16
+ import { applyDropToEvents, buildDropPayload, findEventById, } from "../../event-meta";
17
+ import CalendarToolbar from "../../components/CalendarToolbar";
18
+ import CalendarLegend from "../../components/CalendarLegend";
19
+ import CalendarBoardGrid from "../../components/CalendarBoardGrid";
20
+ import CalendarSidebar from "../../components/CalendarSidebar";
21
+ import { FULL_CALENDAR_VIEW, State } from "./state";
22
+ import "./index.css";
23
+ const CalendarBoard = () => {
24
+ const tab = useTabItem();
25
+ const filterState = useDeepMemo(() => new FilterOptionsContextState({
26
+ defaults: {
27
+ filters: [{ c: "OwnerType", o: "contains", v1: JSON.stringify(["My"]), l: "And" }],
28
+ page: { Page: 1, PageSize: 200 },
29
+ },
30
+ }), []);
31
+ const [state] = useState(new State());
32
+ const [currentTime, setCurrentTime] = useState();
33
+ const [calendarApi, setCalendarApi] = useState();
34
+ const calendarRef = useRef(null);
35
+ const calendar = useCalendarStore();
36
+ useEffect(() => {
37
+ runInAction(() => (tab.title = "Calendar"));
38
+ }, []);
39
+ useEffect(() => {
40
+ setCalendarApi(calendarRef?.current?.getApi());
41
+ }, [calendarRef]);
42
+ useOnDeleteDocument((s, doc) => {
43
+ state.listOptions = state.listOptions.filter((i) => i.source?.id !== doc.id);
44
+ });
45
+ useOnDeleteWorkSchedule((s, doc) => {
46
+ state.listOptions = state.listOptions.filter((i) => i.source?.id !== doc.id);
47
+ });
48
+ useRenderOnChange(() => filterState.options);
49
+ useCalendarListEffect(null, (list) => {
50
+ runInAction(() => {
51
+ const events = list;
52
+ events.forEach((item) => {
53
+ // 事件卡颜色改由 CHIP_COLOR_CLASS 按 source.type 着色(见 event-meta.ts),
54
+ // 这里只补齐 source.title,其余沿用 CalendarMonth 的写法
55
+ if (item.source)
56
+ item.source.title = item.title;
57
+ });
58
+ state.listOptions = events;
59
+ });
60
+ }, filterState.options);
61
+ /**
62
+ * 点击事件卡 / 侧栏条目 → 打开 QuickView。
63
+ *
64
+ * 只把节点的 id 交给 state,弹窗本身由 morpho-document-core 的 QuickView 负责:
65
+ * 它自己 useDocument 加载节点,再按 type 派发到对应 meta 的 getQuickView
66
+ * (Task / WorkSchedule / Meeting … 各有自己的对话框,未注册的 type 落到通用文档视图)。
67
+ */
68
+ const openSource = (source) => state.openQuickView(source?.id);
69
+ /** 切换 month / week / day 视图 */
70
+ const handleChangeType = (value) => {
71
+ runInAction(() => (state.type = value));
72
+ calendarApi?.changeView(FULL_CALENDAR_VIEW[value]);
73
+ };
74
+ /** 日期发生变化的回调 */
75
+ const onChange = (date, dateString) => {
76
+ const dateText = Array.isArray(dateString) ? dateString[0] : dateString;
77
+ setCurrentTime(date);
78
+ if (state.type === "week") {
79
+ calendarApi?.gotoDate(`${dayjs(date).format("YYYY-MM-DD")}`);
80
+ }
81
+ else if (dateText) {
82
+ calendarApi?.gotoDate(dateText);
83
+ }
84
+ };
85
+ /**
86
+ * 当拖动停止并且事件已移至其他日期/时间时触发。
87
+ *
88
+ * 四件事都和「拖完跳回原位 / 刷新后位置不对」有关,逐条说明:
89
+ *
90
+ * 1. 时间格式:交给 buildDropPayload 写成**本地时间**的 `YYYY-MM-DDTHH:mm:ss.SSS`,
91
+ * 而不是 toISOString()(UTC 时刻,UTC+8 下拖到某天零点时日期会退回前一天,
92
+ * 服务端按本地时间解析就落到错误日期)。
93
+ * 2. **先乐观写回本地模型再发请求**:请求往返期间只要有任意一次重渲染,事件源就可能
94
+ * 被重置,本地数据若还停在旧位置,刚拖过去的卡片会立刻被打回原位 —— 这就是
95
+ * 「拖拽当时跳回原位」的直接原因。
96
+ * 3. 失败要可见并回退:原先用 `error: "message"`,Store.action 会吞掉异常只弹个 toast,
97
+ * 事件仍停在拖过去的位置、看着像保存成功。改成回调显式判断,
98
+ * 失败就把本地模型与卡片一起退回拖拽前(changelog 的既有约定:
99
+ * 「改进edit处理,错误时UI重设回原值」)。
100
+ * 4. 事件源引用稳定:见 state.ts 的 sidebarData 与 CalendarBoardGrid 里的 useMemo。
101
+ */
102
+ const eventDrop = async (info) => {
103
+ const id = info.event.id;
104
+ /*
105
+ * 拒绝这次拖拽的三种情况都退回,但各自留下可诊断的线索 ——
106
+ * 静默 revert 的后果就是用户只看到「拖完立刻跳回」,却无从知道为什么。
107
+ */
108
+ if (!info.event.extendedProps.allowChangeStart) {
109
+ // 服务端没给改期权限(或压根没下发这个字段):这是设计如此,直接退回
110
+ console.warn("[CalendarBoard] 该事件不允许改期,已退回", {
111
+ id,
112
+ allowChangeStart: info.event.extendedProps.allowChangeStart,
113
+ extendedProps: Object.keys(info.event.extendedProps ?? {}),
114
+ });
115
+ info.revert();
116
+ return;
117
+ }
118
+ if (!id) {
119
+ // FullCalendar 对没有 id 的事件给的是空字符串,此时无从定位服务端记录
120
+ console.warn("[CalendarBoard] 事件没有 id,无法保存改期结果", {
121
+ title: info.event.title,
122
+ extendedProps: Object.keys(info.event.extendedProps ?? {}),
123
+ });
124
+ info.revert();
125
+ return;
126
+ }
127
+ const drop = { start: info.event.start, end: info.event.end };
128
+ const payload = buildDropPayload(drop);
129
+ if (!payload) {
130
+ console.warn("[CalendarBoard] 拿不到有效的落点时间,已退回", {
131
+ id,
132
+ start: info.event.start,
133
+ end: info.event.end,
134
+ });
135
+ info.revert();
136
+ return;
137
+ }
138
+ // 回退用的快照要从列表里取:info.oldEvent 不保证存在,
139
+ // 拿不到时回退会静默失效 —— 模型留在新位置、卡片却退回原位,两边不一致
140
+ const before = findEventById(state.listOptions, id);
141
+ const rollback = { start: before?.start ?? before?.startDate, end: before?.end };
142
+ runInAction(() => {
143
+ state.listOptions = applyDropToEvents(state.listOptions, id, drop);
144
+ });
145
+ let failed = false;
146
+ await calendar.edit(id, {
147
+ data: payload,
148
+ error: (error) => {
149
+ failed = true;
150
+ message.error(error.message);
151
+ runInAction(() => {
152
+ state.listOptions = applyDropToEvents(state.listOptions, id, rollback);
153
+ });
154
+ info.revert();
155
+ },
156
+ });
157
+ if (failed)
158
+ return;
159
+ };
160
+ return observe(() => {
161
+ /**
162
+ * 侧栏、图例、事件卡的推导(纯前端,见 sidebar-data.ts)。
163
+ *
164
+ * 取的是 state 上的 computed:既保证响应式(observe 是 <Observer>,只追踪它这次
165
+ * 渲染读到的 observable),又保证引用稳定 —— 详见 state.ts 里 sidebarData 的注释。
166
+ */
167
+ const sidebar = state.sidebarData;
168
+ return (React.createElement(ConfigProvider, { theme: antdTheme },
169
+ React.createElement("div", { className: "calendar-board flex h-full w-full flex-col overflow-hidden text-sm" },
170
+ React.createElement(CalendarToolbar, { type: state.type, title: state.title, currentTime: currentTime, onChangeType: handleChangeType, onToday: () => calendarApi?.today(), onPrev: () => calendarApi?.prev(), onNext: () => calendarApi?.next(), onChangeDate: onChange },
171
+ React.createElement(FilterOptionsContext.Provider, { value: filterState },
172
+ React.createElement(FilterView, { columns: [React.createElement(EventsFilter, { key: "EventsFilter", defaultValue: ["My"] })] }))),
173
+ React.createElement(CalendarLegend, { categories: sidebar.summary.categories, onSelectEvent: openSource }),
174
+ React.createElement("div", { className: "flex flex-1 min-h-0 overflow-hidden" },
175
+ React.createElement(CalendarBoardGrid, { events: sidebar.visibleEvents, initialView: state.type, colorMap: sidebar.summary.colorMap, calendarRef: calendarRef, onSelectEvent: openSource, onEventDrop: eventDrop, onDatesSet: (info) => state.datesRender(info) }),
176
+ React.createElement(CalendarSidebar, { upcoming: sidebar.upcoming, search: state.search, tab: state.sidebarTab, onSearch: state.setSearch, onChangeTab: state.setSidebarTab, onSelectEvent: openSource })),
177
+ state.quickViewId ? (React.createElement(QuickView, { id: state.quickViewId, visible: true, onCancel: state.closeQuickView })) : null)));
178
+ });
179
+ };
180
+ export default CalendarBoard;
181
+ //# 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,116 @@
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
+ /** 工具栏 MONTH / WEEK / DAY 按钮 */
62
+ export declare const VIEW_TYPE_OPTIONS: {
63
+ value: CalendarViewType;
64
+ label: string;
65
+ }[];
66
+ /** 侧栏页签 */
67
+ export type CalendarSidebarTab = "upcoming" | "activity";
68
+ export declare class State {
69
+ accessor listOptions: CalendarBoardEvent[];
70
+ /** 当前视图类型 */
71
+ accessor type: CalendarViewType;
72
+ /** FullCalendar 头部日期(由 datesSet 同步) */
73
+ accessor title: string;
74
+ /** 侧栏搜索关键字(纯前端过滤,不触发重新请求) */
75
+ accessor search: string;
76
+ /** 被隐藏的事件分类(source.type) */
77
+ accessor hiddenTypes: Set<string>;
78
+ /** 侧栏页签 */
79
+ accessor sidebarTab: CalendarSidebarTab;
80
+ /** 当前打开的 QuickView 目标节点 id;为空表示没有弹窗 */
81
+ accessor quickViewId: string | undefined;
82
+ /** 呈现一组新日期时触发。 */
83
+ datesRender(info: any): void;
84
+ /**
85
+ * 切换某个分类的显示 / 隐藏。
86
+ *
87
+ * 下面三个 action 写成箭头属性:它们会被直接当作 props 传给侧栏,
88
+ * 方法体里用到 this,脱离实例调用会抛
89
+ * `Cannot set properties of undefined`(MobX 的 action 用调用时的 this 作为 scope)。
90
+ */
91
+ toggleType: (type: string) => void;
92
+ setSearch: (value: string) => void;
93
+ setSidebarTab: (tab: CalendarSidebarTab) => void;
94
+ /**
95
+ * 打开某个节点的 QuickView。
96
+ *
97
+ * 传 id 即可:真正的弹窗由 morpho-document-core 的 QuickView 负责,
98
+ * 它会自己加载节点并按 type 派发到对应 meta 的对话框。
99
+ */
100
+ openQuickView: (id?: string) => void;
101
+ /** 关闭 QuickView */
102
+ closeQuickView: () => void;
103
+ /**
104
+ * 侧栏 / 图例 / 网格共用的推导结果。
105
+ *
106
+ * 用 computed 而不是每次渲染现算,关键是为了**引用稳定**:其中的 visibleEvents 会交给
107
+ * FullCalendar 当 eventSources,而每次渲染都换一个新数组会让 FullCalendar 重置事件源,
108
+ * 用它手上的外部数据覆盖内部状态 —— 刚拖拽出来的位置就会被打回原位。
109
+ * 依赖(listOptions / search / hiddenTypes)不变时,这里返回同一个对象。
110
+ *
111
+ * ⚠️ computed 只在**被观察时**才缓存,所以这个 getter 必须在 observe()(即
112
+ * mobx-react-lite 的 <Observer>)内部读 —— 挪到组件体里就会退化成每次现算,
113
+ * 引用不再稳定,拖拽结果又会被打回原位。测试里用 autorun 复刻了这个前提。
114
+ */
115
+ get sidebarData(): ISidebarData;
116
+ }
@@ -0,0 +1,232 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { action, computed, observable } from "mobx";
3
+ import dayjs from "dayjs";
4
+ import { deriveSidebarData } from "../../sidebar-data";
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 const FULL_CALENDAR_VIEW = {
15
+ month: "dayGridMonth",
16
+ week: "dayGridWeek",
17
+ day: "timeGridDay",
18
+ };
19
+ /**
20
+ * 上班时段:Day 视图只显示这一段,不再铺满 24 小时。
21
+ *
22
+ * slotMaxTime 是**开区间**,所以 09:00–18:00 的最后一格正好是 17:00–18:00。
23
+ * 这两个值目前只用在 timeGridDay;将来若把周视图换成 timeGridWeek,
24
+ * 直接复用即可。
25
+ */
26
+ export const WORKDAY_START_TIME = "09:00:00";
27
+ export const WORKDAY_END_TIME = "18:00:00";
28
+ /**
29
+ * 周视图单列最多显示几条事件,其余收进 +N。
30
+ *
31
+ * 月视图每格只有一两行的空间(全局 DAY_MAX_EVENTS = 2),周视图则是一整列、
32
+ * 稿子里单列排了 5 张卡,所以单独给一个宽松的上限,不跟着月视图一起收紧。
33
+ */
34
+ export const WEEK_MAX_EVENTS = 15;
35
+ /**
36
+ * FullCalendar 的按视图覆盖选项。
37
+ *
38
+ * dayGridWeek 要还原 calendar-week-view.html:表头只留 SUN..SAT、日期标签落在格子里。
39
+ * 收起的口径与月视图不同:不受行数上限约束(dayMaxEventRows: false,同时也让它
40
+ * 不跟着全局的 DAY_MAX_EVENTS 一起收紧),只按 WEEK_MAX_EVENTS 这个事件数上限收起。
41
+ *
42
+ * timeGridDay 只保留上班时段(见 WORKDAY_START_TIME):
43
+ * - slotMinTime / slotMaxTime 裁掉时段外的行;
44
+ * - scrollTime 让初始滚动停在 9:00(默认值是 06:00,裁掉后已经越界);
45
+ * - expandRows 让这 9 小时撑满可用高度,否则默认 30 分钟格高 1.5em,
46
+ * 9 小时只有约 320px,高面板下方会留一大片空白。
47
+ */
48
+ export const FULL_CALENDAR_VIEW_OPTIONS = {
49
+ dayGridWeek: {
50
+ /** 不设行数上限(默认也是 false,这里写出来是为了不被外面的全局配置影响) */
51
+ dayMaxEventRows: false,
52
+ dayMaxEvents: WEEK_MAX_EVENTS,
53
+ dayHeaderFormat: { weekday: "short" },
54
+ dayCellContent: (arg) => dayjs(arg.date).format("MMM D"),
55
+ },
56
+ timeGridDay: {
57
+ slotMinTime: WORKDAY_START_TIME,
58
+ slotMaxTime: WORKDAY_END_TIME,
59
+ scrollTime: WORKDAY_START_TIME,
60
+ expandRows: true,
61
+ },
62
+ };
63
+ /** 工具栏 MONTH / WEEK / DAY 按钮 */
64
+ export const VIEW_TYPE_OPTIONS = [
65
+ { value: "month", label: "MONTH" },
66
+ { value: "week", label: "WEEK" },
67
+ { value: "day", label: "DAY" },
68
+ ];
69
+ let State = (() => {
70
+ let _instanceExtraInitializers = [];
71
+ let _listOptions_decorators;
72
+ let _listOptions_initializers = [];
73
+ let _listOptions_extraInitializers = [];
74
+ let _type_decorators;
75
+ let _type_initializers = [];
76
+ let _type_extraInitializers = [];
77
+ let _title_decorators;
78
+ let _title_initializers = [];
79
+ let _title_extraInitializers = [];
80
+ let _search_decorators;
81
+ let _search_initializers = [];
82
+ let _search_extraInitializers = [];
83
+ let _hiddenTypes_decorators;
84
+ let _hiddenTypes_initializers = [];
85
+ let _hiddenTypes_extraInitializers = [];
86
+ let _sidebarTab_decorators;
87
+ let _sidebarTab_initializers = [];
88
+ let _sidebarTab_extraInitializers = [];
89
+ let _quickViewId_decorators;
90
+ let _quickViewId_initializers = [];
91
+ let _quickViewId_extraInitializers = [];
92
+ let _datesRender_decorators;
93
+ let _toggleType_decorators;
94
+ let _toggleType_initializers = [];
95
+ let _toggleType_extraInitializers = [];
96
+ let _setSearch_decorators;
97
+ let _setSearch_initializers = [];
98
+ let _setSearch_extraInitializers = [];
99
+ let _setSidebarTab_decorators;
100
+ let _setSidebarTab_initializers = [];
101
+ let _setSidebarTab_extraInitializers = [];
102
+ let _openQuickView_decorators;
103
+ let _openQuickView_initializers = [];
104
+ let _openQuickView_extraInitializers = [];
105
+ let _closeQuickView_decorators;
106
+ let _closeQuickView_initializers = [];
107
+ let _closeQuickView_extraInitializers = [];
108
+ let _get_sidebarData_decorators;
109
+ return class State {
110
+ static {
111
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
112
+ _listOptions_decorators = [observable];
113
+ _type_decorators = [observable];
114
+ _title_decorators = [observable];
115
+ _search_decorators = [observable];
116
+ _hiddenTypes_decorators = [observable];
117
+ _sidebarTab_decorators = [observable];
118
+ _quickViewId_decorators = [observable];
119
+ _datesRender_decorators = [action];
120
+ _toggleType_decorators = [action];
121
+ _setSearch_decorators = [action];
122
+ _setSidebarTab_decorators = [action];
123
+ _openQuickView_decorators = [action];
124
+ _closeQuickView_decorators = [action];
125
+ _get_sidebarData_decorators = [computed];
126
+ __esDecorate(this, null, _listOptions_decorators, { kind: "accessor", name: "listOptions", static: false, private: false, access: { has: obj => "listOptions" in obj, get: obj => obj.listOptions, set: (obj, value) => { obj.listOptions = value; } }, metadata: _metadata }, _listOptions_initializers, _listOptions_extraInitializers);
127
+ __esDecorate(this, null, _type_decorators, { kind: "accessor", name: "type", static: false, private: false, access: { has: obj => "type" in obj, get: obj => obj.type, set: (obj, value) => { obj.type = value; } }, metadata: _metadata }, _type_initializers, _type_extraInitializers);
128
+ __esDecorate(this, null, _title_decorators, { kind: "accessor", name: "title", static: false, private: false, access: { has: obj => "title" in obj, get: obj => obj.title, set: (obj, value) => { obj.title = value; } }, metadata: _metadata }, _title_initializers, _title_extraInitializers);
129
+ __esDecorate(this, null, _search_decorators, { kind: "accessor", name: "search", static: false, private: false, access: { has: obj => "search" in obj, get: obj => obj.search, set: (obj, value) => { obj.search = value; } }, metadata: _metadata }, _search_initializers, _search_extraInitializers);
130
+ __esDecorate(this, null, _hiddenTypes_decorators, { kind: "accessor", name: "hiddenTypes", static: false, private: false, access: { has: obj => "hiddenTypes" in obj, get: obj => obj.hiddenTypes, set: (obj, value) => { obj.hiddenTypes = value; } }, metadata: _metadata }, _hiddenTypes_initializers, _hiddenTypes_extraInitializers);
131
+ __esDecorate(this, null, _sidebarTab_decorators, { kind: "accessor", name: "sidebarTab", static: false, private: false, access: { has: obj => "sidebarTab" in obj, get: obj => obj.sidebarTab, set: (obj, value) => { obj.sidebarTab = value; } }, metadata: _metadata }, _sidebarTab_initializers, _sidebarTab_extraInitializers);
132
+ __esDecorate(this, null, _quickViewId_decorators, { kind: "accessor", name: "quickViewId", static: false, private: false, access: { has: obj => "quickViewId" in obj, get: obj => obj.quickViewId, set: (obj, value) => { obj.quickViewId = value; } }, metadata: _metadata }, _quickViewId_initializers, _quickViewId_extraInitializers);
133
+ __esDecorate(this, null, _datesRender_decorators, { kind: "method", name: "datesRender", static: false, private: false, access: { has: obj => "datesRender" in obj, get: obj => obj.datesRender }, metadata: _metadata }, null, _instanceExtraInitializers);
134
+ __esDecorate(this, null, _get_sidebarData_decorators, { kind: "getter", name: "sidebarData", static: false, private: false, access: { has: obj => "sidebarData" in obj, get: obj => obj.sidebarData }, metadata: _metadata }, null, _instanceExtraInitializers);
135
+ __esDecorate(null, null, _toggleType_decorators, { kind: "field", name: "toggleType", static: false, private: false, access: { has: obj => "toggleType" in obj, get: obj => obj.toggleType, set: (obj, value) => { obj.toggleType = value; } }, metadata: _metadata }, _toggleType_initializers, _toggleType_extraInitializers);
136
+ __esDecorate(null, null, _setSearch_decorators, { kind: "field", name: "setSearch", static: false, private: false, access: { has: obj => "setSearch" in obj, get: obj => obj.setSearch, set: (obj, value) => { obj.setSearch = value; } }, metadata: _metadata }, _setSearch_initializers, _setSearch_extraInitializers);
137
+ __esDecorate(null, null, _setSidebarTab_decorators, { kind: "field", name: "setSidebarTab", static: false, private: false, access: { has: obj => "setSidebarTab" in obj, get: obj => obj.setSidebarTab, set: (obj, value) => { obj.setSidebarTab = value; } }, metadata: _metadata }, _setSidebarTab_initializers, _setSidebarTab_extraInitializers);
138
+ __esDecorate(null, null, _openQuickView_decorators, { kind: "field", name: "openQuickView", static: false, private: false, access: { has: obj => "openQuickView" in obj, get: obj => obj.openQuickView, set: (obj, value) => { obj.openQuickView = value; } }, metadata: _metadata }, _openQuickView_initializers, _openQuickView_extraInitializers);
139
+ __esDecorate(null, null, _closeQuickView_decorators, { kind: "field", name: "closeQuickView", static: false, private: false, access: { has: obj => "closeQuickView" in obj, get: obj => obj.closeQuickView, set: (obj, value) => { obj.closeQuickView = value; } }, metadata: _metadata }, _closeQuickView_initializers, _closeQuickView_extraInitializers);
140
+ if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
141
+ }
142
+ #listOptions_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _listOptions_initializers, []));
143
+ get listOptions() { return this.#listOptions_accessor_storage; }
144
+ set listOptions(value) { this.#listOptions_accessor_storage = value; }
145
+ #type_accessor_storage = (__runInitializers(this, _listOptions_extraInitializers), __runInitializers(this, _type_initializers, "month"));
146
+ /** 当前视图类型 */
147
+ get type() { return this.#type_accessor_storage; }
148
+ set type(value) { this.#type_accessor_storage = value; }
149
+ #title_accessor_storage = (__runInitializers(this, _type_extraInitializers), __runInitializers(this, _title_initializers, void 0));
150
+ /** FullCalendar 头部日期(由 datesSet 同步) */
151
+ get title() { return this.#title_accessor_storage; }
152
+ set title(value) { this.#title_accessor_storage = value; }
153
+ #search_accessor_storage = (__runInitializers(this, _title_extraInitializers), __runInitializers(this, _search_initializers, ""));
154
+ /** 侧栏搜索关键字(纯前端过滤,不触发重新请求) */
155
+ get search() { return this.#search_accessor_storage; }
156
+ set search(value) { this.#search_accessor_storage = value; }
157
+ #hiddenTypes_accessor_storage = (__runInitializers(this, _search_extraInitializers), __runInitializers(this, _hiddenTypes_initializers, new Set()));
158
+ /** 被隐藏的事件分类(source.type) */
159
+ get hiddenTypes() { return this.#hiddenTypes_accessor_storage; }
160
+ set hiddenTypes(value) { this.#hiddenTypes_accessor_storage = value; }
161
+ #sidebarTab_accessor_storage = (__runInitializers(this, _hiddenTypes_extraInitializers), __runInitializers(this, _sidebarTab_initializers, "upcoming"));
162
+ /** 侧栏页签 */
163
+ get sidebarTab() { return this.#sidebarTab_accessor_storage; }
164
+ set sidebarTab(value) { this.#sidebarTab_accessor_storage = value; }
165
+ #quickViewId_accessor_storage = (__runInitializers(this, _sidebarTab_extraInitializers), __runInitializers(this, _quickViewId_initializers, undefined));
166
+ /** 当前打开的 QuickView 目标节点 id;为空表示没有弹窗 */
167
+ get quickViewId() { return this.#quickViewId_accessor_storage; }
168
+ set quickViewId(value) { this.#quickViewId_accessor_storage = value; }
169
+ /** 呈现一组新日期时触发。 */
170
+ datesRender(info) {
171
+ this.title = info.view.title;
172
+ }
173
+ /**
174
+ * 切换某个分类的显示 / 隐藏。
175
+ *
176
+ * 下面三个 action 写成箭头属性:它们会被直接当作 props 传给侧栏,
177
+ * 方法体里用到 this,脱离实例调用会抛
178
+ * `Cannot set properties of undefined`(MobX 的 action 用调用时的 this 作为 scope)。
179
+ */
180
+ toggleType = (__runInitializers(this, _quickViewId_extraInitializers), __runInitializers(this, _toggleType_initializers, (type) => {
181
+ if (this.hiddenTypes.has(type)) {
182
+ this.hiddenTypes.delete(type);
183
+ }
184
+ else {
185
+ this.hiddenTypes.add(type);
186
+ }
187
+ }));
188
+ setSearch = (__runInitializers(this, _toggleType_extraInitializers), __runInitializers(this, _setSearch_initializers, (value) => {
189
+ this.search = value;
190
+ }));
191
+ setSidebarTab = (__runInitializers(this, _setSearch_extraInitializers), __runInitializers(this, _setSidebarTab_initializers, (tab) => {
192
+ this.sidebarTab = tab;
193
+ }));
194
+ /**
195
+ * 打开某个节点的 QuickView。
196
+ *
197
+ * 传 id 即可:真正的弹窗由 morpho-document-core 的 QuickView 负责,
198
+ * 它会自己加载节点并按 type 派发到对应 meta 的对话框。
199
+ */
200
+ openQuickView = (__runInitializers(this, _setSidebarTab_extraInitializers), __runInitializers(this, _openQuickView_initializers, (id) => {
201
+ this.quickViewId = id;
202
+ }));
203
+ /** 关闭 QuickView */
204
+ closeQuickView = (__runInitializers(this, _openQuickView_extraInitializers), __runInitializers(this, _closeQuickView_initializers, () => {
205
+ this.quickViewId = undefined;
206
+ }));
207
+ /**
208
+ * 侧栏 / 图例 / 网格共用的推导结果。
209
+ *
210
+ * 用 computed 而不是每次渲染现算,关键是为了**引用稳定**:其中的 visibleEvents 会交给
211
+ * FullCalendar 当 eventSources,而每次渲染都换一个新数组会让 FullCalendar 重置事件源,
212
+ * 用它手上的外部数据覆盖内部状态 —— 刚拖拽出来的位置就会被打回原位。
213
+ * 依赖(listOptions / search / hiddenTypes)不变时,这里返回同一个对象。
214
+ *
215
+ * ⚠️ computed 只在**被观察时**才缓存,所以这个 getter 必须在 observe()(即
216
+ * mobx-react-lite 的 <Observer>)内部读 —— 挪到组件体里就会退化成每次现算,
217
+ * 引用不再稳定,拖拽结果又会被打回原位。测试里用 autorun 复刻了这个前提。
218
+ */
219
+ get sidebarData() {
220
+ return deriveSidebarData({
221
+ events: this.listOptions,
222
+ search: this.search,
223
+ hiddenTypes: this.hiddenTypes,
224
+ });
225
+ }
226
+ constructor() {
227
+ __runInitializers(this, _closeQuickView_extraInitializers);
228
+ }
229
+ };
230
+ })();
231
+ export { State };
232
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../../../../src/modules/calendar-board/pages/CalendarBoard/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type dayjs from "dayjs";
2
+ import { type CalendarBoardEvent, type IEventSummary, type IUpcomingEvent } from "./event-meta";
3
+ export interface ISidebarData {
4
+ /**
5
+ * 分类与配色,基于**全部**事件计算。
6
+ *
7
+ * 必须用全部事件而不是过滤后的事件:否则一旦搜索或隐藏分类,
8
+ * 事件的取色顺序就会变,同一 type 的颜色会跟着漂移。
9
+ */
10
+ summary: IEventSummary;
11
+ /** 搜索 + 隐藏分类过滤后的事件,日历与 UPCOMING 列表共用 */
12
+ visibleEvents: CalendarBoardEvent[];
13
+ /** UPCOMING DEADLINES:今天及以后的事件,按时间升序 */
14
+ upcoming: IUpcomingEvent[];
15
+ }
16
+ /**
17
+ * 侧栏、图例、事件卡共用的推导。
18
+ *
19
+ * 全部是纯前端计算:搜索与分类隐藏都不触发重新请求。
20
+ */
21
+ export declare const deriveSidebarData: (options: {
22
+ events: CalendarBoardEvent[];
23
+ search?: string;
24
+ hiddenTypes?: Iterable<string>;
25
+ /** 以哪一天为「今天」,测试注入固定日期用 */
26
+ from?: dayjs.Dayjs;
27
+ }) => ISidebarData;
@@ -0,0 +1,19 @@
1
+ import { buildUpcoming, filterEvents, summarizeEvents, } from "./event-meta";
2
+ /**
3
+ * 侧栏、图例、事件卡共用的推导。
4
+ *
5
+ * 全部是纯前端计算:搜索与分类隐藏都不触发重新请求。
6
+ */
7
+ export const deriveSidebarData = (options) => {
8
+ const summary = summarizeEvents(options.events);
9
+ const visibleEvents = filterEvents(options.events, {
10
+ search: options.search,
11
+ hiddenTypes: options.hiddenTypes,
12
+ });
13
+ return {
14
+ summary,
15
+ visibleEvents,
16
+ upcoming: buildUpcoming(visibleEvents, summary, { from: options.from }),
17
+ };
18
+ };
19
+ //# sourceMappingURL=sidebar-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sidebar-data.js","sourceRoot":"","sources":["../../../src/modules/calendar-board/sidebar-data.ts"],"names":[],"mappings":"AACA,OAAO,EACN,aAAa,EACb,YAAY,EACZ,eAAe,GAIf,MAAM,cAAc,CAAC;AAgBtB;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAMjC,EAAgB,EAAE;IAClB,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE;QAClD,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,WAAW,EAAE,OAAO,CAAC,WAAW;KAChC,CAAC,CAAC;IAEH,OAAO;QACN,OAAO;QACP,aAAa;QACb,QAAQ,EAAE,aAAa,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;KACvE,CAAC;AACH,CAAC,CAAC"}
@@ -89,7 +89,6 @@ const SubTaskList = ({ header = true, total = true, filterVisible = true, header
89
89
  React.createElement(TaskFilter, { id: user.info.unit.id, key: "TaskFilter" }),
90
90
  React.createElement(TaskStatusFilter, { key: "TaskStatusFilter", ...props.taskStatusFilterProps }),
91
91
  React.createElement(FlagFilter, { key: "FlagFilter" }),
92
- // <AssigneeViewFilter key="AssigneeViewFilter" />,
93
92
  React.createElement(CreateDateFilter, { key: "StartDateFilter", filterBy: "StartDate" }),
94
93
  React.createElement(CreateDateFilter, { key: "DueDateFilter", filterBy: "DueDate" }),
95
94
  ],
@@ -133,9 +132,7 @@ const SubTaskList = ({ header = true, total = true, filterVisible = true, header
133
132
  },
134
133
  },
135
134
  };
136
- return observe(() => (
137
- /** 建立新ListView所需Context. */
138
- React.createElement(ListDataContext.Provider, { value: list },
135
+ return observe(() => (React.createElement(ListDataContext.Provider, { value: list },
139
136
  React.createElement(BatchContext.Provider, { value: batch },
140
137
  React.createElement("div", { style: props.style, className: classnames("sub-task-list", props.className) },
141
138
  !state.showDialog && (React.createElement(ListView, { renderId: parentId, moveAfter: moveAfter, asideable: false, headerProps: {