Skip to content

Expose toUpdatedEvents, toInsertedEvents, toDeletedEvents + Fixed event drag/drop issues. #1369

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

Merged
merged 4 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
expose inserted,updated and deleted events + added startTime,endTime …
…and allDay in edit modal + event dragging fixes
  • Loading branch information
raheeliftikhar5 committed Dec 4, 2024
commit 62c5decc15b3cbf0fdc1a69c17e1c8a1ec6cbbeb
184 changes: 156 additions & 28 deletions client/packages/lowcoder-comps/src/comps/calendarComp/calendarComp.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { default as Form } from "antd/es/form";
import { default as Input } from "antd/es/input";
import { default as ColorPicker } from "antd/es/color-picker";
import { default as Switch } from "antd/es/switch";
import { trans, getCalendarLocale } from "../../i18n/comps";
import { createRef, useContext, useRef, useState, useEffect, useCallback, useMemo, Suspense } from "react";
import dayjs from "dayjs";
Expand All @@ -19,6 +20,7 @@ import momentPlugin from "@fullcalendar/moment";

import ErrorBoundary from "./errorBoundary";
import { default as Tabs } from "antd/es/tabs";
import { differenceBy, differenceWith, isEqual, filter, includes } from "lodash";

import {
isValidColor,
Expand Down Expand Up @@ -54,6 +56,8 @@ import {
migrateOldData,
controlItem,
depsConfig,
stateComp,
JSONObject,
} from 'lowcoder-sdk';

import {
Expand Down Expand Up @@ -196,6 +200,10 @@ let childrenMap: any = {
currentPremiumView: dropdownControl(DefaultWithPremiumViewOptions, "resourceTimelineDay"),
animationStyle: styleControl(AnimationStyle, 'animationStyle'),
showVerticalScrollbar: withDefault(BoolControl, false),
initialData: stateComp<JSONObject>({}),
updatedEvents: stateComp<JSONObject>({}),
insertedEvents: stateComp<JSONObject>({}),
deletedEvents: stateComp<JSONObject>({}),
};

// this should ensure backwards compatibility with older versions of the SDK
Expand Down Expand Up @@ -233,8 +241,9 @@ let CalendarBasicComp = (function () {
currentFreeView?: string;
currentPremiumView?: string;
animationStyle?:any;
modalStyle?:any
showVerticalScrollbar?:boolean
modalStyle?:any;
showVerticalScrollbar?:boolean;
initialData: Array<EventType>;
}, dispatch: any) => {
const comp = useContext(EditorContext)?.getUICompByName(
useContext(CompNameContext)
Expand All @@ -243,11 +252,13 @@ let CalendarBasicComp = (function () {
const theme = useContext(ThemeContext);
const ref = createRef<HTMLDivElement>();
const editEvent = useRef<EventType>();
const initData = useRef<boolean>(false);
const [form] = Form.useForm();
const [left, setLeft] = useState<number | undefined>(undefined);
const [licensed, setLicensed] = useState<boolean>(props.licenseKey !== "");
const [currentSlotLabelFormat, setCurrentSlotLabelFormat] = useState(slotLabelFormat);

const [initDataMap, setInitDataMap] = useState<Record<string, number>>({});

useEffect(() => {
setLicensed(props.licenseKey !== "");
}, [props.licenseKey]);
Expand Down Expand Up @@ -290,27 +301,53 @@ let CalendarBasicComp = (function () {
start: dayjs(item.start, DateParser).format(),
end: dayjs(item.end, DateParser).format(),
allDay: item.allDay,
resourceId: item.resourceId ? item.resourceId : null,
groupId: item.groupId ? item.groupId : null,
...(item.resourceId ? { resourceId: item.resourceId } : {}),
...(item.groupId ? { groupId: item.groupId } : {}),
backgroundColor: item.backgroundColor,
extendedProps: {
color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
...(item.groupId ? { groupId: item.groupId } : {}), // Ensure color is in extendedProps
detail: item.detail,
titleColor:item.titleColor,
detailColor:item.detailColor,
titleFontWeight:item.titleFontWeight,
titleFontStyle:item.titleFontStyle,
detailFontWeight:item.detailFontWeight,
detailFontStyle:item.detailFontStyle,
animation:item?.animation,
animationDelay:item?.animationDelay,
animationDuration:item?.animationDuration,
animationIterationCount:item?.animationIterationCount
}}
extendedProps: { // Ensure color is in extendedProps
color: isValidColor(item.color || "") ? item.color : theme?.theme?.primary,
detail: item.detail,
titleColor:item.titleColor,
detailColor:item.detailColor,
titleFontWeight:item.titleFontWeight,
titleFontStyle:item.titleFontStyle,
detailFontWeight:item.detailFontWeight,
detailFontStyle:item.detailFontStyle,
animation:item?.animation,
animationDelay:item?.animationDelay,
animationDuration:item?.animationDuration,
animationIterationCount:item?.animationIterationCount
}
}
}) : [currentEvents];
}, [currentEvents, theme])

useEffect(() => {
const mapData: Record<string, number> = {};
events?.forEach((item: any, index: number) => {
mapData[`${item.id}`] = index;
})

if (initData.current) {
const difference = differenceWith(events, props.initialData, isEqual);
const inserted = differenceBy(difference, Object.keys(initDataMap)?.map(id => ({ id })), 'id')
const updated = filter(difference, obj => includes(Object.keys(initDataMap), String(obj.id)));
const deleted = differenceBy(props.initialData, Object.keys(mapData)?.map(id => ({ id })), 'id')

comp.children?.comp.children?.updatedEvents.dispatchChangeValueAction(updated);
comp.children?.comp.children?.insertedEvents.dispatchChangeValueAction(inserted);
comp.children?.comp.children?.deletedEvents.dispatchChangeValueAction(deleted);
}

if (!initData.current && events?.length && comp?.children?.comp?.children?.initialData) {
setInitDataMap(mapData);
comp?.children?.comp?.children?.initialData?.dispatch?.(
comp?.children?.comp?.children?.initialData?.changeValueAction?.([...events])
);
initData.current = true;
}
}, [JSON.stringify(events), comp?.children?.comp?.children?.initialData]);

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

// list all plugins for Fullcalendar
Expand Down Expand Up @@ -370,12 +407,12 @@ let CalendarBasicComp = (function () {
}, [slotLabelFormat, slotLabelFormatWeek, slotLabelFormatMonth]);

const handleEventDataChange = useCallback((data: Array<Record<string,any>>) => {
comp.children?.comp.children.events.children.manual.children.manual.dispatch(
comp.children?.comp.children.events.children.manual.children.manual.setChildrensAction(
comp?.children?.comp.children.events.children.manual.children.manual.dispatch(
comp?.children?.comp.children.events.children.manual.children.manual.setChildrensAction(
data
)
);
comp.children?.comp.children.events.children.mapData.children.data.dispatchChangeValueAction(
comp?.children?.comp.children.events.children.mapData.children.data.dispatchChangeValueAction(
JSON.stringify(data)
);
props.onEvent("change");
Expand Down Expand Up @@ -506,6 +543,24 @@ let CalendarBasicComp = (function () {
>
<Input />
</Form.Item>
<Form.Item
label={trans("calendar.eventStartTime")}
name="start"
>
<Input />
</Form.Item>
<Form.Item
label={trans("calendar.eventEndTime")}
name="end"
>
<Input />
</Form.Item>
<Form.Item
label={trans("calendar.eventAllDay")}
name="allDay"
>
<Switch />
</Form.Item>
</FormWrapper>
</Tabs.TabPane>
<Tabs.TabPane tab={trans("calendar.colorStyles")} key="2">
Expand Down Expand Up @@ -768,12 +823,21 @@ let CalendarBasicComp = (function () {
showModal(event, false);
}, [editEvent, showModal]);

const handleDrop = useCallback(() => {
const handleDrop = useCallback((eventInfo: EventType) => {
let eventsList = [...props.events];
const eventIdx = eventsList.findIndex(
(item: EventType) => item.id === eventInfo.id
);
if (eventIdx > -1) {
eventsList[eventIdx] = eventInfo;
handleEventDataChange(eventsList);
}

if (typeof props.onDropEvent === 'function') {
props.onDropEvent("dropEvent");
}
}, [props.onDropEvent]);

return (
<Wrapper
ref={ref}
Expand Down Expand Up @@ -880,9 +944,13 @@ let CalendarBasicComp = (function () {
props.onEvent("change");
}
}}
eventDragStop={(info) => {
eventDrop={(info) => {
const {extendedProps, ...event} = info.event.toJSON();
if (info.view) {
handleDrop();
handleDrop({
...event,
...extendedProps,
});
}
}}
/>
Expand Down Expand Up @@ -1007,6 +1075,30 @@ const TmpCalendarComp = withExposingConfigs(CalendarBasicComp, [
return input.events.filter(event => Boolean(event.resourceId));
},
}),
depsConfig({
name: "toUpdatedEvents",
desc: trans("calendar.updatedEvents"),
depKeys: ["updatedEvents"],
func: (input: { updatedEvents: any[]; }) => {
return input.updatedEvents;
},
}),
depsConfig({
name: "toInsertedEvents",
desc: trans("calendar.insertedEvents"),
depKeys: ["insertedEvents"],
func: (input: { insertedEvents: any[]; }) => {
return input.insertedEvents;
},
}),
depsConfig({
name: "toDeletedEvents",
desc: trans("calendar.deletedEvents"),
depKeys: ["deletedEvents"],
func: (input: { deletedEvents: any[]; }) => {
return input.deletedEvents;
},
}),
]);

let CalendarComp = withMethodExposing(TmpCalendarComp, [
Expand Down Expand Up @@ -1124,7 +1216,43 @@ let CalendarComp = withMethodExposing(TmpCalendarComp, [
const viewKey = comp.children.licenseKey.getView() === "" ? 'defaultFreeView' : 'defaultPremiumView';
comp.children["viewKey"].dispatchChangeValueAction("multiMonthYear");
}
}
},
{
method: {
name: "clearUpdatedEvents",
detail: "Clear updated events list",
params: [],
},
execute: (comp) => {
comp?.children?.updatedEvents.dispatch(
comp?.children?.updatedEvents.changeValueAction([])
);
}
},
{
method: {
name: "clearInsertedEvents",
detail: "Clear inserted events list",
params: [],
},
execute: (comp) => {
comp?.children?.insertedEvents.dispatch(
comp?.children?.insertedEvents.changeValueAction([])
);
}
},
{
method: {
name: "clearDeletedEvents",
detail: "Clear deleted events list",
params: [],
},
execute: (comp) => {
comp?.children?.deletedEvents.dispatch(
comp?.children?.deletedEvents.changeValueAction([])
);
}
},
]);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,25 @@ export const defaultEvents = [
end: dayjs().hour(21).minute(30).second(0).format(DATE_TIME_FORMAT),
color: "#079968",
},
{
id: "6",
label: "Coding",
start: dayjs().hour(15).minute(0).second(0).format(DATE_TIME_FORMAT),
end: dayjs().hour(17).minute(30).second(0).format(DATE_TIME_FORMAT),
color: "#079968",
backgroundColor:"#ffffff",
detail: 'Discuss project milestones and deliverables.',
titleColor:"#000000",
detailColor:"#000000",
titleFontWeight:"normal",
titleFontStyle:"italic",
detailFontWeight:"normal",
detailFontStyle:"italic",
animation:"none",
animationDelay:"0s",
animationDuration:"0s",
animationIterationCount:"0",
},
];
export const resourcesEventsDefaultData = [
{
Expand Down
3 changes: 3 additions & 0 deletions client/packages/lowcoder-comps/src/i18n/comps/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ export const en = {
resourcesDefault: "Rooms",
resourcesName: "Resource Name",
resourcesEvents : "Resources Events Data",
deletedEvents : "List of deleted events",
updatedEvents : "List of updated events",
insertedEvents : "List of inserted events",
editable: "Editable",
license: "Licence Key",
licenseTooltip: "Get your licence key from https://fullcalendar.io/purchase to enable premium views like Resource Timeline and Resource Grid.",
Expand Down