Skip to content

Commit 232bed3

Browse files
fixed issue with dynamic data replaced with json on data updates
1 parent 047a9f1 commit 232bed3

File tree

2 files changed

+120
-95
lines changed

2 files changed

+120
-95
lines changed

Diff for: client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx

+83-94
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import timeGridPlugin from "@fullcalendar/timegrid";
1515
import interactionPlugin, { EventResizeDoneArg } from "@fullcalendar/interaction";
1616
import listPlugin from "@fullcalendar/list";
1717
import allLocales from "@fullcalendar/core/locales-all";
18-
import { EventContentArg, DateSelectArg, EventDropArg } from "@fullcalendar/core";
18+
import { EventContentArg, DateSelectArg, EventDropArg, EventInput } from "@fullcalendar/core";
1919
import momentPlugin from "@fullcalendar/moment";
2020

2121
import ErrorBoundary from "./errorBoundary";
@@ -58,6 +58,8 @@ import {
5858
depsConfig,
5959
stateComp,
6060
JSONObject,
61+
isDynamicSegment,
62+
Theme,
6163
} from 'lowcoder-sdk';
6264

6365
import {
@@ -81,11 +83,14 @@ import {
8183
resourcesDefaultData,
8284
resourceTimeLineHeaderToolbar,
8385
resourceTimeGridHeaderToolbar,
86+
formattedEvents,
8487
} from "./calendarConstants";
8588
import { EventOptionControl } from "./eventOptionsControl";
8689
import { EventImpl } from "@fullcalendar/core/internal";
8790
import DatePicker from "antd/es/date-picker";
8891

92+
type Theme = typeof Theme;
93+
8994
const DATE_TIME_FORMAT = "YYYY-MM-DD HH:mm:ss";
9095

9196
function fixOldData(oldData: any) {
@@ -206,6 +211,7 @@ let childrenMap: any = {
206211
showVerticalScrollbar: withDefault(BoolControl, false),
207212
showResourceEventsInFreeView: withDefault(BoolControl, false),
208213
initialData: stateComp<JSONObject>({}),
214+
updatedEventsData: stateComp<JSONObject>(defaultEvents),
209215
updatedEvents: stateComp<JSONObject>({}),
210216
insertedEvents: stateComp<JSONObject>({}),
211217
deletedEvents: stateComp<JSONObject>({}),
@@ -251,15 +257,16 @@ let CalendarBasicComp = (function () {
251257
showVerticalScrollbar?:boolean;
252258
showResourceEventsInFreeView?: boolean;
253259
initialData: Array<EventType>;
260+
updatedEventsData: Array<EventType>;
254261
inputFormat: string;
255262
}, dispatch: any) => {
256263
const comp = useContext(EditorContext)?.getUICompByName(
257264
useContext(CompNameContext)
258265
);
259266

260-
const theme = useContext(ThemeContext);
267+
const theme: Theme | undefined = useContext(ThemeContext);
261268
const ref = createRef<HTMLDivElement>();
262-
const editEvent = useRef<EventType>();
269+
const editEvent = useRef<EventInput>();
263270
const initData = useRef<boolean>(false);
264271
const [form] = Form.useForm();
265272
const [left, setLeft] = useState<number | undefined>(undefined);
@@ -294,63 +301,75 @@ let CalendarBasicComp = (function () {
294301

295302
const currentEvents = useMemo(() => {
296303
if (props.showResourceEventsInFreeView && Boolean(props.licenseKey)) {
297-
return props.events.filter((event: { resourceId: any; }) => Boolean(event.resourceId))
304+
return props.updatedEventsData.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
298305
}
299306
return currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
300-
? props.events.filter((event: { resourceId: any; }) => Boolean(event.resourceId))
301-
: props.events.filter((event: { resourceId: any; }) => !Boolean(event.resourceId));
307+
? props.updatedEventsData.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
308+
: props.updatedEventsData.filter((event: { resourceId?: any; }) => !Boolean(event.resourceId));
302309
}, [
303310
currentView,
304-
props.events,
311+
props.updatedEventsData,
305312
props.showResourceEventsInFreeView,
306313
])
307314

308315
// we use one central stack of events for all views
309-
const events = useMemo(() => {
310-
return Array.isArray(currentEvents) ? currentEvents.map((item: EventType) => {
311-
return {
312-
title: item.label,
313-
id: item.id,
314-
start: dayjs(item.start, DateParser).format(),
315-
end: dayjs(item.end, DateParser).format(),
316-
allDay: item.allDay,
317-
...(item.resourceId ? { resourceId: item.resourceId } : {}),
318-
...(item.groupId ? { groupId: item.groupId } : {}),
319-
backgroundColor: item.backgroundColor,
320-
extendedProps: { // Ensure color is in extendedProps
321-
color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
322-
detail: item.detail,
323-
titleColor:item.titleColor,
324-
detailColor:item.detailColor,
325-
titleFontWeight:item.titleFontWeight,
326-
titleFontStyle:item.titleFontStyle,
327-
detailFontWeight:item.detailFontWeight,
328-
detailFontStyle:item.detailFontStyle,
329-
animation:item?.animation,
330-
animationDelay:item?.animationDelay,
331-
animationDuration:item?.animationDuration,
332-
animationIterationCount:item?.animationIterationCount
333-
}
334-
}
335-
}) : [currentEvents];
316+
const events: EventInput = useMemo(() => {
317+
return formattedEvents(currentEvents, theme);
336318
}, [currentEvents, theme])
337319

320+
const initialEvents = useMemo(() => {
321+
let eventsList:EventType[] = [];
322+
if (props.showResourceEventsInFreeView && Boolean(props.licenseKey)) {
323+
eventsList = props.events.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
324+
}
325+
else {
326+
if (currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay") {
327+
eventsList = props.events.filter((event: { resourceId?: any; }) => Boolean(event.resourceId))
328+
} else {
329+
eventsList = props.events.filter((event: { resourceId?: any; }) => !Boolean(event.resourceId));
330+
}
331+
}
332+
333+
return eventsList.map(event => ({
334+
...event,
335+
start: dayjs(event.start, DateParser).format(),
336+
end: dayjs(event.end, DateParser).format(),
337+
}));
338+
}, [
339+
JSON.stringify(props.events),
340+
])
341+
342+
useEffect(() => {
343+
initData.current = false;
344+
}, [JSON.stringify(props.events)]);
345+
338346
useEffect(() => {
339347
if (initData.current) return;
340348

341349
const mapData: Record<string, number> = {};
342-
events?.forEach((item: any, index: number) => {
350+
initialEvents?.forEach((item: any, index: number) => {
343351
mapData[`${item.id}`] = index;
344352
})
345353

346-
if (!initData.current && events?.length && comp?.children?.comp?.children?.initialData) {
354+
if (!initData.current && initialEvents?.length && comp?.children?.comp?.children?.initialData) {
347355
setInitDataMap(mapData);
348356
comp?.children?.comp?.children?.initialData?.dispatch?.(
349-
comp?.children?.comp?.children?.initialData?.changeValueAction?.([...events])
357+
comp?.children?.comp?.children?.initialData?.changeValueAction?.([...initialEvents])
358+
);
359+
360+
const eventsList = props.events.map((event: EventType) => ({
361+
...event,
362+
start: dayjs(event.start, DateParser).format(),
363+
end: dayjs(event.end, DateParser).format(),
364+
}));
365+
366+
comp?.children?.comp?.children?.updatedEventsData?.dispatch?.(
367+
comp?.children?.comp?.children?.updatedEventsData?.changeValueAction?.(eventsList)
350368
);
369+
351370
initData.current = true;
352371
}
353-
}, [JSON.stringify(events), comp?.children?.comp?.children?.initialData]);
372+
}, [JSON.stringify(initialEvents), comp?.children?.comp?.children?.initialData]);
354373

355374
const resources = useMemo(() => props.resources.value, [props.resources.value]);
356375

@@ -413,35 +432,10 @@ let CalendarBasicComp = (function () {
413432
const findUpdatedInsertedDeletedEvents = useCallback((data: Array<EventType>) => {
414433
if (!initData.current) return;
415434

416-
let eventsData: Array<Record<string, any>> = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
435+
const eventsData: Array<EventType> = currentView == "resourceTimelineDay" || currentView == "resourceTimeGridDay"
417436
? data.filter((event: { resourceId?: string; }) => Boolean(event.resourceId))
418437
: data.filter((event: { resourceId?: string; }) => !Boolean(event.resourceId));
419438

420-
eventsData = eventsData.map((item) => ({
421-
title: item.label,
422-
id: item.id,
423-
start: dayjs(item.start, DateParser).format(),
424-
end: dayjs(item.end, DateParser).format(),
425-
allDay: item.allDay,
426-
...(item.resourceId ? { resourceId: item.resourceId } : {}),
427-
...(item.groupId ? { groupId: item.groupId } : {}),
428-
backgroundColor: item.backgroundColor,
429-
extendedProps: { // Ensure color is in extendedProps
430-
color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
431-
detail: item.detail,
432-
titleColor:item.titleColor,
433-
detailColor:item.detailColor,
434-
titleFontWeight:item.titleFontWeight,
435-
titleFontStyle:item.titleFontStyle,
436-
detailFontWeight:item.detailFontWeight,
437-
detailFontStyle:item.detailFontStyle,
438-
animation:item?.animation,
439-
animationDelay:item?.animationDelay,
440-
animationDuration:item?.animationDuration,
441-
animationIterationCount:item?.animationIterationCount
442-
}
443-
}));
444-
445439
const mapData: Record<string, number> = {};
446440
eventsData?.forEach((item: any, index: number) => {
447441
mapData[`${item.id}`] = index;
@@ -458,13 +452,8 @@ let CalendarBasicComp = (function () {
458452
}, [initDataMap, currentView, props.initialData, initData.current]);
459453

460454
const handleEventDataChange = useCallback((data: Array<EventType>) => {
461-
comp?.children?.comp.children.events.children.manual.children.manual.dispatch(
462-
comp?.children?.comp.children.events.children.manual.children.manual.setChildrensAction(
463-
data
464-
)
465-
);
466-
comp?.children?.comp.children.events.children.mapData.children.data.dispatchChangeValueAction(
467-
JSON.stringify(data)
455+
comp?.children?.comp?.children?.updatedEventsData?.dispatch?.(
456+
comp?.children?.comp?.children?.updatedEventsData?.changeValueAction?.(data)
468457
);
469458

470459
findUpdatedInsertedDeletedEvents(data);
@@ -522,7 +511,7 @@ let CalendarBasicComp = (function () {
522511
className="event-remove"
523512
onClick={(e) => {
524513
e.stopPropagation();
525-
const events = props.events.filter(
514+
const events = props.updatedEventsData.filter(
526515
(item: EventType) => item.id !== eventInfo.event.id
527516
);
528517
handleEventDataChange(events);
@@ -541,7 +530,7 @@ let CalendarBasicComp = (function () {
541530
}, [
542531
theme,
543532
props.style,
544-
props.events,
533+
props.updatedEventsData,
545534
props.showAllDay,
546535
handleEventDataChange,
547536
]);
@@ -780,7 +769,7 @@ let CalendarBasicComp = (function () {
780769
end,
781770
allDay,
782771
} = form.getFieldsValue();
783-
const idExist = props.events.findIndex(
772+
const idExist = props.updatedEventsData.findIndex(
784773
(item: EventType) => item.id === id
785774
);
786775
if (idExist > -1 && id !== eventId) {
@@ -790,7 +779,7 @@ let CalendarBasicComp = (function () {
790779
throw new Error();
791780
}
792781
if (ifEdit) {
793-
const changeEvents = props.events.map((item: EventType) => {
782+
const changeEvents = props.updatedEventsData.map((item: EventType) => {
794783
if (item.id === eventId) {
795784
return {
796785
...item,
@@ -843,7 +832,7 @@ let CalendarBasicComp = (function () {
843832
...(titleColor !== undefined ? { titleColor } : null),
844833
...(detailColor !== undefined ? { detailColor } : null),
845834
};
846-
handleEventDataChange([...props.events, createInfo]);
835+
handleEventDataChange([...props.updatedEventsData, createInfo]);
847836
}
848837
form.resetFields();
849838
}); //small change
@@ -855,14 +844,14 @@ let CalendarBasicComp = (function () {
855844
}, [
856845
form,
857846
editEvent,
858-
props.events,
847+
props.updatedEventsData,
859848
props?.modalStyle,
860849
props?.animationStyle,
861850
handleEventDataChange,
862851
]);
863852

864853
const handleDbClick = useCallback(() => {
865-
const event = props.events.find(
854+
const event = props.updatedEventsData.find(
866855
(item: EventType) => item.id === editEvent.current?.id
867856
) as EventType;
868857
if (!props.editable || !editEvent.current) {
@@ -880,7 +869,7 @@ let CalendarBasicComp = (function () {
880869
}
881870
}, [
882871
editEvent,
883-
props.events,
872+
props.updatedEventsData,
884873
props.editable,
885874
onEventVal,
886875
showModal,
@@ -911,7 +900,7 @@ let CalendarBasicComp = (function () {
911900
const updateEventsOnDragOrResize = useCallback((eventInfo: EventImpl) => {
912901
const {extendedProps, title, ...event} = eventInfo.toJSON();
913902

914-
let eventsList = [...props.events];
903+
let eventsList = [...props.updatedEventsData];
915904
const eventIdx = eventsList.findIndex(
916905
(item: EventType) => item.id === event.id
917906
);
@@ -923,7 +912,7 @@ let CalendarBasicComp = (function () {
923912
};
924913
handleEventDataChange(eventsList);
925914
}
926-
}, [props.events, handleEventDataChange]);
915+
}, [props.updatedEventsData, handleEventDataChange]);
927916

928917
const handleDrop = useCallback((eventInfo: EventDropArg) => {
929918
updateEventsOnDragOrResize(eventInfo.event);
@@ -987,7 +976,7 @@ let CalendarBasicComp = (function () {
987976
select={(info) => handleCreate(info)}
988977
eventClick={(info) => {
989978
const event = events.find(
990-
(item: EventType) => item.id === info.event.id
979+
(item: EventInput) => item.id === info.event.id
991980
);
992981
editEvent.current = event;
993982
setTimeout(() => {
@@ -1018,9 +1007,9 @@ let CalendarBasicComp = (function () {
10181007
}}
10191008
eventsSet={(info) => {
10201009
let needChange = false;
1021-
let changeEvents: EventType[] = [];
1010+
let changeEvents: EventInput[] = [];
10221011
info.forEach((item) => {
1023-
const event = events.find((i: EventType) => i.id === item.id);
1012+
const event = events.find((i: EventInput) => i.id === item.id);
10241013
const start = dayjs(item.start, DateParser).format();
10251014
const end = dayjs(item.end, DateParser).format();
10261015
if (
@@ -1076,7 +1065,7 @@ let CalendarBasicComp = (function () {
10761065
style: { getPropertyView: () => any; };
10771066
animationStyle: { getPropertyView: () => any; };
10781067
modalStyle: { getPropertyView: () => any; };
1079-
licenseKey: { getView: () => any; propertyView: (arg0: { label: string; }) => any; };
1068+
licenseKey: { getView: () => any; propertyView: (arg0: { label: string; tooltip: string }) => any; };
10801069
showVerticalScrollbar: { propertyView: (arg0: { label: string; }) => any; };
10811070
showResourceEventsInFreeView: { propertyView: (arg0: { label: string; }) => any; };
10821071
inputFormat: { propertyView: (arg0: {}) => any; };
@@ -1172,25 +1161,25 @@ const TmpCalendarComp = withExposingConfigs(CalendarBasicComp, [
11721161
depsConfig({
11731162
name: "allEvents",
11741163
desc: trans("calendar.events"),
1175-
depKeys: ["events"],
1176-
func: (input: { events: any[]; }) => {
1177-
return input.events;
1164+
depKeys: ["updatedEventsData"],
1165+
func: (input: { updatedEventsData: any[]; }) => {
1166+
return input.updatedEventsData;
11781167
},
11791168
}),
11801169
depsConfig({
11811170
name: "events",
11821171
desc: trans("calendar.events"),
1183-
depKeys: ["events"],
1184-
func: (input: { events: any[]; }) => {
1185-
return input.events.filter(event => !Boolean(event.resourceId));
1172+
depKeys: ["updatedEventsData"],
1173+
func: (input: { updatedEventsData: any[]; }) => {
1174+
return input.updatedEventsData.filter(event => !Boolean(event.resourceId));
11861175
},
11871176
}),
11881177
depsConfig({
11891178
name: "resourcesEvents",
11901179
desc: trans("calendar.resourcesEvents"),
1191-
depKeys: ["events"],
1192-
func: (input: { events: any[]; }) => {
1193-
return input.events.filter(event => Boolean(event.resourceId));
1180+
depKeys: ["updatedEventsData"],
1181+
func: (input: { updatedEventsData: any[]; }) => {
1182+
return input.updatedEventsData.filter(event => Boolean(event.resourceId));
11941183
},
11951184
}),
11961185
depsConfig({

0 commit comments

Comments
 (0)