1
1
import { default as Form } from "antd/es/form" ;
2
2
import { default as Input } from "antd/es/input" ;
3
3
import { default as ColorPicker } from "antd/es/color-picker" ;
4
+ import { default as Switch } from "antd/es/switch" ;
4
5
import { trans , getCalendarLocale } from "../../i18n/comps" ;
5
6
import { createRef , useContext , useRef , useState , useEffect , useCallback , useMemo , Suspense } from "react" ;
6
7
import dayjs from "dayjs" ;
@@ -19,6 +20,7 @@ import momentPlugin from "@fullcalendar/moment";
19
20
20
21
import ErrorBoundary from "./errorBoundary" ;
21
22
import { default as Tabs } from "antd/es/tabs" ;
23
+ import { differenceBy , differenceWith , isEqual , filter , includes } from "lodash" ;
22
24
23
25
import {
24
26
isValidColor ,
@@ -54,6 +56,8 @@ import {
54
56
migrateOldData ,
55
57
controlItem ,
56
58
depsConfig ,
59
+ stateComp ,
60
+ JSONObject ,
57
61
} from 'lowcoder-sdk' ;
58
62
59
63
import {
@@ -196,6 +200,10 @@ let childrenMap: any = {
196
200
currentPremiumView : dropdownControl ( DefaultWithPremiumViewOptions , "resourceTimelineDay" ) ,
197
201
animationStyle : styleControl ( AnimationStyle , 'animationStyle' ) ,
198
202
showVerticalScrollbar : withDefault ( BoolControl , false ) ,
203
+ initialData : stateComp < JSONObject > ( { } ) ,
204
+ updatedEvents : stateComp < JSONObject > ( { } ) ,
205
+ insertedEvents : stateComp < JSONObject > ( { } ) ,
206
+ deletedEvents : stateComp < JSONObject > ( { } ) ,
199
207
} ;
200
208
201
209
// this should ensure backwards compatibility with older versions of the SDK
@@ -233,8 +241,9 @@ let CalendarBasicComp = (function () {
233
241
currentFreeView ?: string ;
234
242
currentPremiumView ?: string ;
235
243
animationStyle ?:any ;
236
- modalStyle ?:any
237
- showVerticalScrollbar ?:boolean
244
+ modalStyle ?:any ;
245
+ showVerticalScrollbar ?:boolean ;
246
+ initialData : Array < EventType > ;
238
247
} , dispatch : any ) => {
239
248
const comp = useContext ( EditorContext ) ?. getUICompByName (
240
249
useContext ( CompNameContext )
@@ -243,11 +252,13 @@ let CalendarBasicComp = (function () {
243
252
const theme = useContext ( ThemeContext ) ;
244
253
const ref = createRef < HTMLDivElement > ( ) ;
245
254
const editEvent = useRef < EventType > ( ) ;
255
+ const initData = useRef < boolean > ( false ) ;
246
256
const [ form ] = Form . useForm ( ) ;
247
257
const [ left , setLeft ] = useState < number | undefined > ( undefined ) ;
248
258
const [ licensed , setLicensed ] = useState < boolean > ( props . licenseKey !== "" ) ;
249
259
const [ currentSlotLabelFormat , setCurrentSlotLabelFormat ] = useState ( slotLabelFormat ) ;
250
-
260
+ const [ initDataMap , setInitDataMap ] = useState < Record < string , number > > ( { } ) ;
261
+
251
262
useEffect ( ( ) => {
252
263
setLicensed ( props . licenseKey !== "" ) ;
253
264
} , [ props . licenseKey ] ) ;
@@ -290,27 +301,53 @@ let CalendarBasicComp = (function () {
290
301
start : dayjs ( item . start , DateParser ) . format ( ) ,
291
302
end : dayjs ( item . end , DateParser ) . format ( ) ,
292
303
allDay : item . allDay ,
293
- resourceId : item . resourceId ? item . resourceId : null ,
294
- groupId : item . groupId ? item . groupId : null ,
304
+ ... ( item . resourceId ? { resourceId : item . resourceId } : { } ) ,
305
+ ... ( item . groupId ? { groupId : item . groupId } : { } ) ,
295
306
backgroundColor : item . backgroundColor ,
296
- extendedProps : {
297
- color : isValidColor ( item . color || "" ) ? item . color : theme ?. theme ?. primary ,
298
- ... ( item . groupId ? { groupId : item . groupId } : { } ) , // Ensure color is in extendedProps
299
- detail : item . detail ,
300
- titleColor :item . titleColor ,
301
- detailColor :item . detailColor ,
302
- titleFontWeight :item . titleFontWeight ,
303
- titleFontStyle :item . titleFontStyle ,
304
- detailFontWeight :item . detailFontWeight ,
305
- detailFontStyle :item . detailFontStyle ,
306
- animation :item ?. animation ,
307
- animationDelay :item ?. animationDelay ,
308
- animationDuration :item ?. animationDuration ,
309
- animationIterationCount : item ?. animationIterationCount
310
- } }
307
+ extendedProps : { // Ensure color is in extendedProps
308
+ color : isValidColor ( item . color || "" ) ? item . color : theme ?. theme ?. primary ,
309
+ detail : item . detail ,
310
+ titleColor : item . titleColor ,
311
+ detailColor :item . detailColor ,
312
+ titleFontWeight :item . titleFontWeight ,
313
+ titleFontStyle :item . titleFontStyle ,
314
+ detailFontWeight :item . detailFontWeight ,
315
+ detailFontStyle :item . detailFontStyle ,
316
+ animation :item ?. animation ,
317
+ animationDelay :item ?. animationDelay ,
318
+ animationDuration :item ?. animationDuration ,
319
+ animationIterationCount :item ?. animationIterationCount
320
+ }
321
+ }
311
322
} ) : [ currentEvents ] ;
312
323
} , [ currentEvents , theme ] )
313
324
325
+ useEffect ( ( ) => {
326
+ const mapData : Record < string , number > = { } ;
327
+ events ?. forEach ( ( item : any , index : number ) => {
328
+ mapData [ `${ item . id } ` ] = index ;
329
+ } )
330
+
331
+ if ( initData . current ) {
332
+ const difference = differenceWith ( events , props . initialData , isEqual ) ;
333
+ const inserted = differenceBy ( difference , Object . keys ( initDataMap ) ?. map ( id => ( { id } ) ) , 'id' )
334
+ const updated = filter ( difference , obj => includes ( Object . keys ( initDataMap ) , String ( obj . id ) ) ) ;
335
+ const deleted = differenceBy ( props . initialData , Object . keys ( mapData ) ?. map ( id => ( { id } ) ) , 'id' )
336
+
337
+ comp . children ?. comp . children ?. updatedEvents . dispatchChangeValueAction ( updated ) ;
338
+ comp . children ?. comp . children ?. insertedEvents . dispatchChangeValueAction ( inserted ) ;
339
+ comp . children ?. comp . children ?. deletedEvents . dispatchChangeValueAction ( deleted ) ;
340
+ }
341
+
342
+ if ( ! initData . current && events ?. length && comp ?. children ?. comp ?. children ?. initialData ) {
343
+ setInitDataMap ( mapData ) ;
344
+ comp ?. children ?. comp ?. children ?. initialData ?. dispatch ?.(
345
+ comp ?. children ?. comp ?. children ?. initialData ?. changeValueAction ?.( [ ...events ] )
346
+ ) ;
347
+ initData . current = true ;
348
+ }
349
+ } , [ JSON . stringify ( events ) , comp ?. children ?. comp ?. children ?. initialData ] ) ;
350
+
314
351
const resources = useMemo ( ( ) => props . resources . value , [ props . resources . value ] ) ;
315
352
316
353
// list all plugins for Fullcalendar
@@ -370,12 +407,12 @@ let CalendarBasicComp = (function () {
370
407
} , [ slotLabelFormat , slotLabelFormatWeek , slotLabelFormatMonth ] ) ;
371
408
372
409
const handleEventDataChange = useCallback ( ( data : Array < Record < string , any > > ) => {
373
- comp . children ?. comp . children . events . children . manual . children . manual . dispatch (
374
- comp . children ?. comp . children . events . children . manual . children . manual . setChildrensAction (
410
+ comp ? .children ?. comp . children . events . children . manual . children . manual . dispatch (
411
+ comp ? .children ?. comp . children . events . children . manual . children . manual . setChildrensAction (
375
412
data
376
413
)
377
414
) ;
378
- comp . children ?. comp . children . events . children . mapData . children . data . dispatchChangeValueAction (
415
+ comp ? .children ?. comp . children . events . children . mapData . children . data . dispatchChangeValueAction (
379
416
JSON . stringify ( data )
380
417
) ;
381
418
props . onEvent ( "change" ) ;
@@ -506,6 +543,24 @@ let CalendarBasicComp = (function () {
506
543
>
507
544
< Input />
508
545
</ Form . Item >
546
+ < Form . Item
547
+ label = { trans ( "calendar.eventStartTime" ) }
548
+ name = "start"
549
+ >
550
+ < Input />
551
+ </ Form . Item >
552
+ < Form . Item
553
+ label = { trans ( "calendar.eventEndTime" ) }
554
+ name = "end"
555
+ >
556
+ < Input />
557
+ </ Form . Item >
558
+ < Form . Item
559
+ label = { trans ( "calendar.eventAllDay" ) }
560
+ name = "allDay"
561
+ >
562
+ < Switch />
563
+ </ Form . Item >
509
564
</ FormWrapper >
510
565
</ Tabs . TabPane >
511
566
< Tabs . TabPane tab = { trans ( "calendar.colorStyles" ) } key = "2" >
@@ -768,12 +823,21 @@ let CalendarBasicComp = (function () {
768
823
showModal ( event , false ) ;
769
824
} , [ editEvent , showModal ] ) ;
770
825
771
- const handleDrop = useCallback ( ( ) => {
826
+ const handleDrop = useCallback ( ( eventInfo : EventType ) => {
827
+ let eventsList = [ ...props . events ] ;
828
+ const eventIdx = eventsList . findIndex (
829
+ ( item : EventType ) => item . id === eventInfo . id
830
+ ) ;
831
+ if ( eventIdx > - 1 ) {
832
+ eventsList [ eventIdx ] = eventInfo ;
833
+ handleEventDataChange ( eventsList ) ;
834
+ }
835
+
772
836
if ( typeof props . onDropEvent === 'function' ) {
773
837
props . onDropEvent ( "dropEvent" ) ;
774
838
}
775
839
} , [ props . onDropEvent ] ) ;
776
-
840
+
777
841
return (
778
842
< Wrapper
779
843
ref = { ref }
@@ -880,9 +944,13 @@ let CalendarBasicComp = (function () {
880
944
props . onEvent ( "change" ) ;
881
945
}
882
946
} }
883
- eventDragStop = { ( info ) => {
947
+ eventDrop = { ( info ) => {
948
+ const { extendedProps, ...event } = info . event . toJSON ( ) ;
884
949
if ( info . view ) {
885
- handleDrop ( ) ;
950
+ handleDrop ( {
951
+ ...event ,
952
+ ...extendedProps ,
953
+ } ) ;
886
954
}
887
955
} }
888
956
/>
@@ -1007,6 +1075,30 @@ const TmpCalendarComp = withExposingConfigs(CalendarBasicComp, [
1007
1075
return input . events . filter ( event => Boolean ( event . resourceId ) ) ;
1008
1076
} ,
1009
1077
} ) ,
1078
+ depsConfig ( {
1079
+ name : "toUpdatedEvents" ,
1080
+ desc : trans ( "calendar.updatedEvents" ) ,
1081
+ depKeys : [ "updatedEvents" ] ,
1082
+ func : ( input : { updatedEvents : any [ ] ; } ) => {
1083
+ return input . updatedEvents ;
1084
+ } ,
1085
+ } ) ,
1086
+ depsConfig ( {
1087
+ name : "toInsertedEvents" ,
1088
+ desc : trans ( "calendar.insertedEvents" ) ,
1089
+ depKeys : [ "insertedEvents" ] ,
1090
+ func : ( input : { insertedEvents : any [ ] ; } ) => {
1091
+ return input . insertedEvents ;
1092
+ } ,
1093
+ } ) ,
1094
+ depsConfig ( {
1095
+ name : "toDeletedEvents" ,
1096
+ desc : trans ( "calendar.deletedEvents" ) ,
1097
+ depKeys : [ "deletedEvents" ] ,
1098
+ func : ( input : { deletedEvents : any [ ] ; } ) => {
1099
+ return input . deletedEvents ;
1100
+ } ,
1101
+ } ) ,
1010
1102
] ) ;
1011
1103
1012
1104
let CalendarComp = withMethodExposing ( TmpCalendarComp , [
@@ -1124,7 +1216,43 @@ let CalendarComp = withMethodExposing(TmpCalendarComp, [
1124
1216
const viewKey = comp . children . licenseKey . getView ( ) === "" ? 'defaultFreeView' : 'defaultPremiumView' ;
1125
1217
comp . children [ "viewKey" ] . dispatchChangeValueAction ( "multiMonthYear" ) ;
1126
1218
}
1127
- }
1219
+ } ,
1220
+ {
1221
+ method : {
1222
+ name : "clearUpdatedEvents" ,
1223
+ detail : "Clear updated events list" ,
1224
+ params : [ ] ,
1225
+ } ,
1226
+ execute : ( comp ) => {
1227
+ comp ?. children ?. updatedEvents . dispatch (
1228
+ comp ?. children ?. updatedEvents . changeValueAction ( [ ] )
1229
+ ) ;
1230
+ }
1231
+ } ,
1232
+ {
1233
+ method : {
1234
+ name : "clearInsertedEvents" ,
1235
+ detail : "Clear inserted events list" ,
1236
+ params : [ ] ,
1237
+ } ,
1238
+ execute : ( comp ) => {
1239
+ comp ?. children ?. insertedEvents . dispatch (
1240
+ comp ?. children ?. insertedEvents . changeValueAction ( [ ] )
1241
+ ) ;
1242
+ }
1243
+ } ,
1244
+ {
1245
+ method : {
1246
+ name : "clearDeletedEvents" ,
1247
+ detail : "Clear deleted events list" ,
1248
+ params : [ ] ,
1249
+ } ,
1250
+ execute : ( comp ) => {
1251
+ comp ?. children ?. deletedEvents . dispatch (
1252
+ comp ?. children ?. deletedEvents . changeValueAction ( [ ] )
1253
+ ) ;
1254
+ }
1255
+ } ,
1128
1256
] ) ;
1129
1257
1130
1258
0 commit comments